diff options
author | anand <anekkunt@redhat.com> | 2015-04-17 14:19:46 +0530 |
---|---|---|
committer | Vijay Bellur <vbellur@redhat.com> | 2015-04-28 01:53:28 -0700 |
commit | ada6b3a8800867934af57a57d5312f5a5d8374f0 (patch) | |
tree | e6e7c6fa2c22c00fd0dd62be86f460adb0c98c27 /libglusterfs/src/syncop.h | |
parent | d4889b2cfd29e6ecc911d2b29d1f85d516a66eaf (diff) |
libglusterfs: Implementation of sync lock as recursive lock to avoid crash.
Problem : In glusterd,we are using big lock which is implemented based on sync
task frame work for thread synchronization and rcu lock for data consistency.
sync task frame work swap the threads if there is no worker poll threads
available,due to this rcu lock and rcu unlock was happening in different threads
(urcu-bp will not allow this),resulting into glusterd crash.
fix : To avoid releasing the sync lock(big lock) in between rcu critical
section,implemented sync lock as recursive lock.
More details:
link : http://www.spinics.net/lists/gluster-devel/msg14632.html
Change-Id: I2b56c1caf3f0470f219b1adcaf62cce29cdc6b88
BUG: 1211640
Signed-off-by: anand <anekkunt@redhat.com>
Reviewed-on: http://review.gluster.org/10285
Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Tested-by: NetBSD Build System
Reviewed-by: Vijay Bellur <vbellur@redhat.com>
Diffstat (limited to 'libglusterfs/src/syncop.h')
-rw-r--r-- | libglusterfs/src/syncop.h | 26 |
1 files changed, 20 insertions, 6 deletions
diff --git a/libglusterfs/src/syncop.h b/libglusterfs/src/syncop.h index 3a7798fa17e..f41706a9d37 100644 --- a/libglusterfs/src/syncop.h +++ b/libglusterfs/src/syncop.h @@ -114,12 +114,26 @@ struct syncenv { }; +typedef enum { + LOCK_NULL = 0, + LOCK_TASK, + LOCK_THREAD +} lock_type_t; + +typedef enum { + SYNC_LOCK_DEFAULT = 0, + SYNC_LOCK_RECURSIVE, /*it allows recursive locking*/ +} lock_attr_t; + struct synclock { - pthread_mutex_t guard; /* guard the remaining members, pair @cond */ - pthread_cond_t cond; /* waiting non-synctasks */ - struct list_head waitq; /* waiting synctasks */ - gf_boolean_t lock; /* _gf_true or _gf_false, lock status */ - struct synctask *owner; /* NULL if current owner is not a synctask */ + pthread_mutex_t guard; /* guard the remaining members, pair @cond */ + pthread_cond_t cond; /* waiting non-synctasks */ + struct list_head waitq; /* waiting synctasks */ + volatile int lock; /* true(non zero) or false(zero), lock status */ + lock_attr_t attr; + struct synctask *owner; /* NULL if current owner is not a synctask */ + pthread_t owner_tid; + lock_type_t type; }; typedef struct synclock synclock_t; @@ -336,7 +350,7 @@ syncop_create_frame (xlator_t *this) return frame; } -int synclock_init (synclock_t *lock); +int synclock_init (synclock_t *lock, lock_attr_t attr); int synclock_destroy (synclock_t *lock); int synclock_lock (synclock_t *lock); int synclock_trylock (synclock_t *lock); |