summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorshishir gowda <shishirng@gluster.com>2011-03-23 03:53:28 +0000
committerVijay Bellur <vijay@dev.gluster.com>2011-03-23 04:55:34 -0700
commitbd132d8e410dbc24cbef751925cd937939f35747 (patch)
tree23b432233a93884ba13bc16cdc5f8774ecde483a
parent9bd4f25b6b0ea8103324b685fcc21525a29849a8 (diff)
Prevent deadlock in io-stats list management of top.v3.2.0qa4
Senario: thread t1 has lock on the queue, and waits on the element lock to remove it and unref it. Thread t2 has a lock on the element being removed from the queue, but waiting on the queue on the list to update it. The fix is to move list management to outside of the lock. Additonal to this change is adding locks to ios_stat_ref Signed-off-by: shishir gowda <shishirng@gluster.com> Signed-off-by: Vijay Bellur <vijay@dev.gluster.com> BUG: 2578 (Mountpoint hung while running the dbench) URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=2578
-rw-r--r--xlators/debug/io-stats/src/io-stats.c20
1 files changed, 15 insertions, 5 deletions
diff --git a/xlators/debug/io-stats/src/io-stats.c b/xlators/debug/io-stats/src/io-stats.c
index c96603b82..b7c522fe5 100644
--- a/xlators/debug/io-stats/src/io-stats.c
+++ b/xlators/debug/io-stats/src/io-stats.c
@@ -253,16 +253,18 @@ struct ios_local {
#define BUMP_STATS(iosstat, type) \
do { \
struct ios_conf *conf = NULL; \
+ uint64_t value = 0; \
\
conf = this->private; \
\
LOCK(&iosstat->lock); \
{ \
iosstat->counters[type]++; \
- ios_stat_add_to_list (&conf->list[type], \
- iosstat->counters[type], iosstat); \
+ value = iosstat->counters[type]; \
} \
UNLOCK (&iosstat->lock); \
+ ios_stat_add_to_list (&conf->list[type], \
+ value, iosstat); \
\
} while (0)
@@ -273,6 +275,7 @@ struct ios_local {
double elapsed; \
struct timeval *begin, *end; \
double throughput; \
+ int flag = 0; \
\
begin = &frame->begin; \
end = &frame->end; \
@@ -290,11 +293,13 @@ struct ios_local {
throughput; \
gettimeofday (&iosstat-> \
thru_counters[type].time, NULL); \
- ios_stat_add_to_list (&conf->thru_list[type], \
- throughput, iosstat); \
+ flag = 1; \
} \
} \
UNLOCK (&iosstat->lock); \
+ if (flag) \
+ ios_stat_add_to_list (&conf->thru_list[type], \
+ throughput, iosstat); \
} while (0)
int
@@ -329,7 +334,12 @@ ios_fd_ctx_set (fd_t *fd, xlator_t *this, struct ios_fd *iosfd)
int
ios_stat_ref (struct ios_stat *iosstat)
{
- iosstat->refcnt++;
+ LOCK (&iosstat->lock);
+ {
+ iosstat->refcnt++;
+ }
+ UNLOCK (&iosstat->lock);
+
return iosstat->refcnt;
}