Re: [PATCH 10/10 V4] workqueue: merge the role of rebind_hold to idle_done

2012-09-04 Thread Lai Jiangshan
On 09/05/2012 09:15 AM, Tejun Heo wrote:
> On Sun, Sep 02, 2012 at 12:28:28AM +0800, Lai Jiangshan wrote:
>> Currently is single pass, we can wait on idle_done instead wait on 
>> rebind_hold.
>> So we can remove rebind_hold and make the code simpler.
> 
> As I wrote before, in general, I do like this approach; however, the
> implementation in this series seems to make the code longer, which
> kinda defeats its purpose of simplifying the implementation.  It could
> be because the series is mixing fixes with restructuring.  

> Can you
> please re-spin the restructuring part once fixes are settled?  Let's
> see if that actually makes things simpler.

OK for me.

Patch 5:  -4
Patch 6:  -9Patch 5,6 simplify idle rebind(benefit from Patch 2)
Patch 7:  +31
Patch 8:  +14   Patch 7,8 make busy worker wait idle worker's rebinding
Patch 9:  -7
Patch 10: -13   Patch 9,10 single pass

total:  +11 single pass allows us clean up more, example narrow the 
critical
critical section of manage_mutex. I will add it in next 
round.

thank,
Lai

> 
> Thanks!
> 

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 10/10 V4] workqueue: merge the role of rebind_hold to idle_done

2012-09-04 Thread Tejun Heo
On Sun, Sep 02, 2012 at 12:28:28AM +0800, Lai Jiangshan wrote:
> Currently is single pass, we can wait on idle_done instead wait on 
> rebind_hold.
> So we can remove rebind_hold and make the code simpler.

As I wrote before, in general, I do like this approach; however, the
implementation in this series seems to make the code longer, which
kinda defeats its purpose of simplifying the implementation.  It could
be because the series is mixing fixes with restructuring.  Can you
please re-spin the restructuring part once fixes are settled?  Let's
see if that actually makes things simpler.

Thanks!

-- 
tejun
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/



[PATCH 10/10 V4] workqueue: merge the role of rebind_hold to idle_done

2012-09-01 Thread Lai Jiangshan
Currently is single pass, we can wait on idle_done instead wait on rebind_hold.
So we can remove rebind_hold and make the code simpler.

Signed-off-by: Lai Jiangshan 
---
 kernel/workqueue.c |   35 +++
 1 files changed, 11 insertions(+), 24 deletions(-)

diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 6d68571..6411616 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -1309,9 +1309,6 @@ struct idle_rebind {
int   idle_cnt; /* # idle workers to be rebound */
struct completion idle_done;/* all idle workers rebound */
 
-   /* idle workers wait all idles to be rebound */
-   struct completion rebind_hold;
-
/*
 * notify the rebind_workers() that:
 * 1. All idle workers are rebound.
@@ -1340,7 +1337,7 @@ static void synchronize_all_idles_rebound(struct 
global_cwq *gcwq,
 {
 
/* wait for rebind_workers() to notify that all idles are rebound */
-   wait_for_completion(&idle_rebind->rebind_hold);
+   wait_for_completion(&idle_rebind->idle_done);
 
/* finished synchronizing, put reference */
spin_lock_irq(&gcwq->lock);
@@ -1371,7 +1368,7 @@ static void idle_worker_rebind(struct worker *worker)
 
/* this worker has been rebound */
if (!--idle_rebind->idle_cnt)
-   complete(&idle_rebind->idle_done);
+   complete_all(&idle_rebind->idle_done);
spin_unlock_irq(&gcwq->lock);
 
synchronize_all_idles_rebound(gcwq, idle_rebind);
@@ -1447,17 +1444,15 @@ static void rebind_workers(struct global_cwq *gcwq)
lockdep_assert_held(&pool->manager_mutex);
 
/*
-* Rebind idle workers.  Interlocked both ways in triple waits.
-* We wait for workers to rebind via @idle_rebind.idle_done.
-* Workers will wait for us via @idle_rebind.rebind_hold.
-* And them we wait for workers to leave rebind_hold
-* via @idle_rebind.ref_done.
+* Rebind idle workers. Idle workers wait each other to rebind via
+* synchronize_all_idles_rebound(). We wait for all idle workers
+* to rebind via synchronize_all_idles_rebound() too.
+* And them we wait for all workers finish synchronizing and
+* release the ref of @idle_rebind via @idle_rebind.ref_done.
 */
init_completion(&idle_rebind.idle_done);
-   init_completion(&idle_rebind.rebind_hold);
init_completion(&idle_rebind.ref_done);
idle_rebind.ref_cnt = 1;
-   gcwq->idle_rebind = &idle_rebind;
idle_rebind.idle_cnt = 1;
 
/* set REBIND and kick idle ones, we'll wait for these later */
@@ -1497,23 +1492,15 @@ static void rebind_workers(struct global_cwq *gcwq)
}
 
/*
-* we will leave rebind_workers(), have to wait until no worker
-* has ref to this idle_rebind.
+* we will leave rebind_workers(), have to wait until all idles
+* are rebound and until no worker has ref to this idle_rebind.
 */
if (--idle_rebind.idle_cnt) {
+   gcwq->idle_rebind = &idle_rebind;
spin_unlock_irq(&gcwq->lock);
-   wait_for_completion(&idle_rebind.idle_done);
-   spin_lock_irq(&gcwq->lock);
-   }
-
-   complete_all(&idle_rebind.rebind_hold);
-
-   if (--idle_rebind.ref_cnt) {
-   spin_unlock_irq(&gcwq->lock);
+   synchronize_all_idles_rebound(gcwq, &idle_rebind);
wait_for_completion(&idle_rebind.ref_done);
spin_lock_irq(&gcwq->lock);
-   } else {
-   gcwq->idle_rebind = NULL;
}
 }
 
-- 
1.7.4.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/