summaryrefslogtreecommitdiffstats
path: root/xlators/cluster/afr/src
diff options
context:
space:
mode:
authorRavishankar N <ravishankar@redhat.com>2017-03-21 11:02:32 +0530
committerPranith Kumar Karampuri <pkarampu@redhat.com>2017-03-28 18:34:48 -0400
commit0f98f5c8070904810252c6fc1df23747afa4b1d7 (patch)
treeb670fd9a069a509e127c68725483a33ff85451f6 /xlators/cluster/afr/src
parentdf189a8644d7a805bb3e278f61983c5ba8619188 (diff)
syncop: don't wake task in synctask_wake unless really needed
Problem: In EC and AFR, we launch synctasks during self-heal. (i) These tasks usually stackwind a FOP to all its children and call synctask_yield() which does a swapcontext to synctask_switchto() and puts the task in syncenv's waitq by calling __wait(task). This happends as long as the FOP ckbs from all children haven't been received. (ii) For each FOP cbk, we call synctask_wake() which again does a swapcontext to synctask_switchto() which now puts the task in syncenv's runq by calling __run(task). When the task runs and the conext switches back to the FOP path, it puts the task in waitq because we haven't heard from all children as explained in (i). Thus we are unnecessarily using the swapcontext syscalls to just toggle the task back and forth between the waitq and runq. Fix: Store the stackwind count in new variable 'syncbarrier->waitfor' before winding the fop. In each cbk when we call synctask_wake(), perform an actual wake only if the cbk count == stackwind count. Change-Id: Id62d3b6ffed5a8c50f8b79267fb34e9470ba5ed5 BUG: 1434274 Signed-off-by: Ravishankar N <ravishankar@redhat.com> Signed-off-by: Ashish Pandey <aspandey@redhat.com> Reviewed-on: https://review.gluster.org/16931 Smoke: Gluster Build System <jenkins@build.gluster.org> Reviewed-by: Niels de Vos <ndevos@redhat.com> NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org> CentOS-regression: Gluster Build System <jenkins@build.gluster.org> Reviewed-by: Pranith Kumar Karampuri <pkarampu@redhat.com>
Diffstat (limited to 'xlators/cluster/afr/src')
-rw-r--r--xlators/cluster/afr/src/afr-self-heal.h24
1 files changed, 16 insertions, 8 deletions
diff --git a/xlators/cluster/afr/src/afr-self-heal.h b/xlators/cluster/afr/src/afr-self-heal.h
index 0a3d6482ca3..735e520070e 100644
--- a/xlators/cluster/afr/src/afr-self-heal.h
+++ b/xlators/cluster/afr/src/afr-self-heal.h
@@ -19,16 +19,23 @@
#define AFR_ONALL(frame, rfn, fop, args ...) do { \
afr_local_t *__local = frame->local; \
afr_private_t *__priv = frame->this->private; \
- int __i = 0, __count = 0; \
+ int __i = 0, __count = 0; \
+ unsigned char *__child_up = NULL; \
+ \
+ __child_up = alloca0 (__priv->child_count); \
+ memcpy (__child_up, __priv->child_up, \
+ sizeof (*__child_up) * __priv->child_count); \
+ __count = AFR_COUNT (__child_up, __priv->child_count); \
\
- afr_local_replies_wipe (__local, __priv); \
+ __local->barrier.waitfor = __count; \
+ afr_local_replies_wipe (__local, __priv); \
\
for (__i = 0; __i < __priv->child_count; __i++) { \
- if (!__priv->child_up[__i]) continue; \
+ if (!__child_up[__i]) \
+ continue; \
STACK_WIND_COOKIE (frame, rfn, (void *)(long) __i, \
__priv->children[__i], \
__priv->children[__i]->fops->fop, args); \
- __count++; \
} \
syncbarrier_wait (&__local->barrier, __count); \
} while (0)
@@ -40,16 +47,17 @@
#define AFR_ONLIST(list, frame, rfn, fop, args ...) do { \
afr_local_t *__local = frame->local; \
afr_private_t *__priv = frame->this->private; \
- int __i = 0, __count = 0; \
+ int __i = 0; \
+ int __count = AFR_COUNT (list, __priv->child_count); \
\
- afr_local_replies_wipe (__local, __priv); \
+ __local->barrier.waitfor = __count; \
+ afr_local_replies_wipe (__local, __priv); \
\
for (__i = 0; __i < __priv->child_count; __i++) { \
if (!list[__i]) continue; \
STACK_WIND_COOKIE (frame, rfn, (void *)(long) __i, \
__priv->children[__i], \
__priv->children[__i]->fops->fop, args); \
- __count++; \
} \
syncbarrier_wait (&__local->barrier, __count); \
} while (0)
@@ -60,7 +68,7 @@
afr_private_t *__priv = frame->this->private; \
int __i = 0; \
\
- afr_local_replies_wipe (__local, __priv); \
+ afr_local_replies_wipe (__local, __priv); \
\
for (__i = 0; __i < __priv->child_count; __i++) { \
if (!__priv->child_up[__i]) continue; \