Re: [PATCH 05/10] smp: Fast path check on IPI list

2014-07-29 Thread Frederic Weisbecker
On Tue, Jul 29, 2014 at 02:07:39PM +0200, Peter Zijlstra wrote:
> On Mon, Jul 28, 2014 at 07:37:31PM +0200, Frederic Weisbecker wrote:
> > When we enqueue a remote irq work, we trigger the same IPI as those
> > raised by smp_call_function_*() family.
> > 
> > So when we receive such IPI, we check both irq_work and smp_call_function
> > queues. Thus if we trigger a remote irq work, we'll likely find the
> > smp_call_function queue empty unless we collide with concurrent enqueuers
> > but the probability is low.
> > 
> > Meanwhile, checking the smp_call_function queue can be costly because
> > we use llist_del_all() which relies on cmpxchg().
> 
> xchg()

It's still costly though as it's an atomic read/write with full barrier. I'll
update the comment meanwhile.
--
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 05/10] smp: Fast path check on IPI list

2014-07-29 Thread Frederic Weisbecker
On Tue, Jul 29, 2014 at 02:07:39PM +0200, Peter Zijlstra wrote:
> On Mon, Jul 28, 2014 at 07:37:31PM +0200, Frederic Weisbecker wrote:
> > When we enqueue a remote irq work, we trigger the same IPI as those
> > raised by smp_call_function_*() family.
> > 
> > So when we receive such IPI, we check both irq_work and smp_call_function
> > queues. Thus if we trigger a remote irq work, we'll likely find the
> > smp_call_function queue empty unless we collide with concurrent enqueuers
> > but the probability is low.
> > 
> > Meanwhile, checking the smp_call_function queue can be costly because
> > we use llist_del_all() which relies on cmpxchg().
> 
> xchg()

Ah, right!
--
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 05/10] smp: Fast path check on IPI list

2014-07-29 Thread Peter Zijlstra
On Mon, Jul 28, 2014 at 07:37:31PM +0200, Frederic Weisbecker wrote:
> When we enqueue a remote irq work, we trigger the same IPI as those
> raised by smp_call_function_*() family.
> 
> So when we receive such IPI, we check both irq_work and smp_call_function
> queues. Thus if we trigger a remote irq work, we'll likely find the
> smp_call_function queue empty unless we collide with concurrent enqueuers
> but the probability is low.
> 
> Meanwhile, checking the smp_call_function queue can be costly because
> we use llist_del_all() which relies on cmpxchg().

xchg()
--
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 05/10] smp: Fast path check on IPI list

2014-07-29 Thread Peter Zijlstra
On Mon, Jul 28, 2014 at 07:37:31PM +0200, Frederic Weisbecker wrote:
 When we enqueue a remote irq work, we trigger the same IPI as those
 raised by smp_call_function_*() family.
 
 So when we receive such IPI, we check both irq_work and smp_call_function
 queues. Thus if we trigger a remote irq work, we'll likely find the
 smp_call_function queue empty unless we collide with concurrent enqueuers
 but the probability is low.
 
 Meanwhile, checking the smp_call_function queue can be costly because
 we use llist_del_all() which relies on cmpxchg().

xchg()
--
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 05/10] smp: Fast path check on IPI list

2014-07-29 Thread Frederic Weisbecker
On Tue, Jul 29, 2014 at 02:07:39PM +0200, Peter Zijlstra wrote:
 On Mon, Jul 28, 2014 at 07:37:31PM +0200, Frederic Weisbecker wrote:
  When we enqueue a remote irq work, we trigger the same IPI as those
  raised by smp_call_function_*() family.
  
  So when we receive such IPI, we check both irq_work and smp_call_function
  queues. Thus if we trigger a remote irq work, we'll likely find the
  smp_call_function queue empty unless we collide with concurrent enqueuers
  but the probability is low.
  
  Meanwhile, checking the smp_call_function queue can be costly because
  we use llist_del_all() which relies on cmpxchg().
 
 xchg()

Ah, right!
--
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 05/10] smp: Fast path check on IPI list

2014-07-29 Thread Frederic Weisbecker
On Tue, Jul 29, 2014 at 02:07:39PM +0200, Peter Zijlstra wrote:
 On Mon, Jul 28, 2014 at 07:37:31PM +0200, Frederic Weisbecker wrote:
  When we enqueue a remote irq work, we trigger the same IPI as those
  raised by smp_call_function_*() family.
  
  So when we receive such IPI, we check both irq_work and smp_call_function
  queues. Thus if we trigger a remote irq work, we'll likely find the
  smp_call_function queue empty unless we collide with concurrent enqueuers
  but the probability is low.
  
  Meanwhile, checking the smp_call_function queue can be costly because
  we use llist_del_all() which relies on cmpxchg().
 
 xchg()

It's still costly though as it's an atomic read/write with full barrier. I'll
update the comment meanwhile.
--
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 05/10] smp: Fast path check on IPI list

2014-07-28 Thread Frederic Weisbecker
When we enqueue a remote irq work, we trigger the same IPI as those
raised by smp_call_function_*() family.

So when we receive such IPI, we check both irq_work and smp_call_function
queues. Thus if we trigger a remote irq work, we'll likely find the
smp_call_function queue empty unless we collide with concurrent enqueuers
but the probability is low.

Meanwhile, checking the smp_call_function queue can be costly because
we use llist_del_all() which relies on cmpxchg().

We can reduce this overhead by doing a fast path check with llist_empty().
Given the implicit IPI ordering:

   EnqueuerDequeuer
   -   
   llist_add(csd, queue)   get_IPI() {
   send_IPI()  if (llist_empty(queue)
...
When the IPI is sent, we are guaranteed that the IPI receiver will
see the new csd.

So lets do the fast path check to optimize non smp_call_function() related
jobs.

Cc: Ingo Molnar 
Cc: Nicolas Pitre 
Cc: Paul E. McKenney 
Cc: Peter Zijlstra 
Cc: Steven Rostedt 
Cc: Thomas Gleixner 
Cc: Viresh Kumar 
Signed-off-by: Frederic Weisbecker 
---
 kernel/smp.c | 11 ++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/kernel/smp.c b/kernel/smp.c
index 12c5bea..09ddc92 100644
--- a/kernel/smp.c
+++ b/kernel/smp.c
@@ -184,11 +184,19 @@ static int generic_exec_single(int cpu, struct 
call_single_data *csd,
  */
 void generic_smp_call_function_single_interrupt(void)
 {
+   struct llist_head *head = &__get_cpu_var(call_single_queue);
struct llist_node *entry;
struct call_single_data *csd, *csd_next;
static bool warned;
 
-   entry = llist_del_all(&__get_cpu_var(call_single_queue));
+   /*
+* Fast check: in case of irq work remote queue, the IPI list
+* is likely empty. We can spare the expensive llist_del_all().
+*/
+   if (llist_empty(head))
+   goto irq_work;
+
+   entry = llist_del_all(head);
entry = llist_reverse_order(entry);
 
/*
@@ -212,6 +220,7 @@ void generic_smp_call_function_single_interrupt(void)
csd_unlock(csd);
}
 
+irq_work:
/*
 * Handle irq works queued remotely by irq_work_queue_on().
 * Smp functions above are typically synchronous so they
-- 
1.8.3.1

--
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 05/10] smp: Fast path check on IPI list

2014-07-28 Thread Frederic Weisbecker
When we enqueue a remote irq work, we trigger the same IPI as those
raised by smp_call_function_*() family.

So when we receive such IPI, we check both irq_work and smp_call_function
queues. Thus if we trigger a remote irq work, we'll likely find the
smp_call_function queue empty unless we collide with concurrent enqueuers
but the probability is low.

Meanwhile, checking the smp_call_function queue can be costly because
we use llist_del_all() which relies on cmpxchg().

We can reduce this overhead by doing a fast path check with llist_empty().
Given the implicit IPI ordering:

   EnqueuerDequeuer
   -   
   llist_add(csd, queue)   get_IPI() {
   send_IPI()  if (llist_empty(queue)
...
When the IPI is sent, we are guaranteed that the IPI receiver will
see the new csd.

So lets do the fast path check to optimize non smp_call_function() related
jobs.

Cc: Ingo Molnar mi...@kernel.org
Cc: Nicolas Pitre nicolas.pi...@linaro.org
Cc: Paul E. McKenney paul...@linux.vnet.ibm.com
Cc: Peter Zijlstra pet...@infradead.org
Cc: Steven Rostedt rost...@goodmis.org
Cc: Thomas Gleixner t...@linutronix.de
Cc: Viresh Kumar viresh.ku...@linaro.org
Signed-off-by: Frederic Weisbecker fweis...@gmail.com
---
 kernel/smp.c | 11 ++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/kernel/smp.c b/kernel/smp.c
index 12c5bea..09ddc92 100644
--- a/kernel/smp.c
+++ b/kernel/smp.c
@@ -184,11 +184,19 @@ static int generic_exec_single(int cpu, struct 
call_single_data *csd,
  */
 void generic_smp_call_function_single_interrupt(void)
 {
+   struct llist_head *head = __get_cpu_var(call_single_queue);
struct llist_node *entry;
struct call_single_data *csd, *csd_next;
static bool warned;
 
-   entry = llist_del_all(__get_cpu_var(call_single_queue));
+   /*
+* Fast check: in case of irq work remote queue, the IPI list
+* is likely empty. We can spare the expensive llist_del_all().
+*/
+   if (llist_empty(head))
+   goto irq_work;
+
+   entry = llist_del_all(head);
entry = llist_reverse_order(entry);
 
/*
@@ -212,6 +220,7 @@ void generic_smp_call_function_single_interrupt(void)
csd_unlock(csd);
}
 
+irq_work:
/*
 * Handle irq works queued remotely by irq_work_queue_on().
 * Smp functions above are typically synchronous so they
-- 
1.8.3.1

--
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 05/10] smp: Fast path check on IPI list

2014-07-18 Thread Frederic Weisbecker
When we enqueue a remote irq work, we trigger the same IPI as those
raised by smp_call_function_*() family.

So when we receive such IPI, we check both irq_work and smp_call_function
queues. Thus if we trigger a remote irq work, we'll likely find the
smp_call_function queue empty unless we collide with concurrent enqueuers
but the probability is low.

Meanwhile, checking the smp_call_function queue can be costly because
we use llist_del_all() which relies on cmpxchg().

We can reduce this overhead by doing a fast path check with llist_empty().
Given the implicit IPI ordering:

   EnqueuerDequeuer
   -   
   llist_add(csd, queue)   get_IPI() {
   send_IPI()  if (llist_empty(queue)
...
When the IPI is sent, we are guaranteed that the IPI receiver will
see the new csd.

So lets do the fast path check to optimize non smp_call_function() related
jobs.

Cc: Ingo Molnar 
Cc: Paul E. McKenney 
Cc: Peter Zijlstra 
Cc: Steven Rostedt 
Cc: Thomas Gleixner 
Cc: Viresh Kumar 
Signed-off-by: Frederic Weisbecker 
---
 kernel/smp.c | 11 ++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/kernel/smp.c b/kernel/smp.c
index a1812d1..34378d4 100644
--- a/kernel/smp.c
+++ b/kernel/smp.c
@@ -184,11 +184,19 @@ static int generic_exec_single(int cpu, struct 
call_single_data *csd,
  */
 void generic_smp_call_function_single_interrupt(void)
 {
+   struct llist_head *head = &__get_cpu_var(call_single_queue);
struct llist_node *entry;
struct call_single_data *csd, *csd_next;
static bool warned;
 
-   entry = llist_del_all(&__get_cpu_var(call_single_queue));
+   /*
+* Fast check: in case of irq work remote queue, the IPI list
+* is likely empty. We can spare the expensive llist_del_all().
+*/
+   if (llist_empty(head))
+   goto irq_work;
+
+   entry = llist_del_all(head);
entry = llist_reverse_order(entry);
 
/*
@@ -212,6 +220,7 @@ void generic_smp_call_function_single_interrupt(void)
csd_unlock(csd);
}
 
+irq_work:
/*
 * Handle irq works queued remotely by irq_work_queue_on().
 * Smp functions above are typically synchronous so they
-- 
1.8.3.1

--
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 05/10] smp: Fast path check on IPI list

2014-07-18 Thread Frederic Weisbecker
When we enqueue a remote irq work, we trigger the same IPI as those
raised by smp_call_function_*() family.

So when we receive such IPI, we check both irq_work and smp_call_function
queues. Thus if we trigger a remote irq work, we'll likely find the
smp_call_function queue empty unless we collide with concurrent enqueuers
but the probability is low.

Meanwhile, checking the smp_call_function queue can be costly because
we use llist_del_all() which relies on cmpxchg().

We can reduce this overhead by doing a fast path check with llist_empty().
Given the implicit IPI ordering:

   EnqueuerDequeuer
   -   
   llist_add(csd, queue)   get_IPI() {
   send_IPI()  if (llist_empty(queue)
...
When the IPI is sent, we are guaranteed that the IPI receiver will
see the new csd.

So lets do the fast path check to optimize non smp_call_function() related
jobs.

Cc: Ingo Molnar mi...@kernel.org
Cc: Paul E. McKenney paul...@linux.vnet.ibm.com
Cc: Peter Zijlstra pet...@infradead.org
Cc: Steven Rostedt rost...@goodmis.org
Cc: Thomas Gleixner t...@linutronix.de
Cc: Viresh Kumar viresh.ku...@linaro.org
Signed-off-by: Frederic Weisbecker fweis...@gmail.com
---
 kernel/smp.c | 11 ++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/kernel/smp.c b/kernel/smp.c
index a1812d1..34378d4 100644
--- a/kernel/smp.c
+++ b/kernel/smp.c
@@ -184,11 +184,19 @@ static int generic_exec_single(int cpu, struct 
call_single_data *csd,
  */
 void generic_smp_call_function_single_interrupt(void)
 {
+   struct llist_head *head = __get_cpu_var(call_single_queue);
struct llist_node *entry;
struct call_single_data *csd, *csd_next;
static bool warned;
 
-   entry = llist_del_all(__get_cpu_var(call_single_queue));
+   /*
+* Fast check: in case of irq work remote queue, the IPI list
+* is likely empty. We can spare the expensive llist_del_all().
+*/
+   if (llist_empty(head))
+   goto irq_work;
+
+   entry = llist_del_all(head);
entry = llist_reverse_order(entry);
 
/*
@@ -212,6 +220,7 @@ void generic_smp_call_function_single_interrupt(void)
csd_unlock(csd);
}
 
+irq_work:
/*
 * Handle irq works queued remotely by irq_work_queue_on().
 * Smp functions above are typically synchronous so they
-- 
1.8.3.1

--
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/