All of lore.kernel.org
 help / color / mirror / Atom feed
From: David Daney <ddaney@caviumnetworks.com>
To: Aaro Koskinen <aaro.koskinen@iki.fi>
Cc: <devel@driverdev.osuosl.org>, <linux-mips@linux-mips.org>,
	"Greg Kroah-Hartman" <gregkh@linuxfoundation.org>,
	David Daney <david.daney@cavium.com>, <richard@nod.at>
Subject: Re: [PATCH 1/2] staging: octeon-ethernet: don't assume that CPU 0 is special
Date: Mon, 30 Sep 2013 12:41:59 -0700	[thread overview]
Message-ID: <5249D407.2090904@caviumnetworks.com> (raw)
In-Reply-To: <20130930193502.GE4572@blackmetal.musicnaut.iki.fi>

On 09/30/2013 12:35 PM, Aaro Koskinen wrote:
> Hi,
>
> On Mon, Sep 30, 2013 at 10:23:10AM -0700, David Daney wrote:
>> On 09/28/2013 12:50 PM, Aaro Koskinen wrote:
>>> Currently the driver assumes that CPU 0 is handling all the hard IRQs.
>>> This is wrong in Linux SMP systems where user is allowed to assign to
>>> hardware IRQs to any CPU. The driver will stop working if user sets
>>> smp_affinity so that interrupts end up being handled by other than CPU
>>> 0. The patch fixes that.
>>>
>>> Signed-off-by: Aaro Koskinen <aaro.koskinen@iki.fi>
>>> ---
>>>   drivers/staging/octeon/ethernet-rx.c | 12 ++++++------
>>>   1 file changed, 6 insertions(+), 6 deletions(-)
>>>
>>> diff --git a/drivers/staging/octeon/ethernet-rx.c b/drivers/staging/octeon/ethernet-rx.c
>>> index e14a1bb..de831c1 100644
>>> --- a/drivers/staging/octeon/ethernet-rx.c
>>> +++ b/drivers/staging/octeon/ethernet-rx.c
>>> @@ -80,6 +80,8 @@ struct cvm_oct_core_state {
>>>
>>>   static struct cvm_oct_core_state core_state __cacheline_aligned_in_smp;
>>>
>>> +static int cvm_irq_cpu = -1;
>>> +
>>>   static void cvm_oct_enable_napi(void *_)
>>>   {
>>>   	int cpu = smp_processor_id();
>>> @@ -112,11 +114,7 @@ static void cvm_oct_no_more_work(void)
>>>   {
>>>   	int cpu = smp_processor_id();
>>>
>>> -	/*
>>> -	 * CPU zero is special.  It always has the irq enabled when
>>> -	 * waiting for incoming packets.
>>> -	 */
>>> -	if (cpu == 0) {
>>> +	if (cpu == cvm_irq_cpu) {
>>>   		enable_irq(OCTEON_IRQ_WORKQ0 + pow_receive_group);
>>>   		return;
>>>   	}
>>> @@ -135,6 +133,7 @@ static irqreturn_t cvm_oct_do_interrupt(int cpl, void *dev_id)
>>>   {
>>>   	/* Disable the IRQ and start napi_poll. */
>>>   	disable_irq_nosync(OCTEON_IRQ_WORKQ0 + pow_receive_group);
>>> +	cvm_irq_cpu = smp_processor_id();
>>>   	cvm_oct_enable_napi(NULL);
>>>
>>>   	return IRQ_HANDLED;
>>> @@ -547,8 +546,9 @@ void cvm_oct_rx_initialize(void)
>>>   	cvmx_write_csr(CVMX_POW_WQ_INT_PC, int_pc.u64);
>>>
>>>
>>> -	/* Scheduld NAPI now.  This will indirectly enable interrupts. */
>>> +	/* Schedule NAPI now. */
>>>   	cvm_oct_enable_one_cpu();
>>> +	enable_irq(OCTEON_IRQ_WORKQ0 + pow_receive_group);
>>
>> The fact that you have to manually enable irqs here indicates that
>> the patch is not good.
>>
>> Either the enable_irq() is unnecessary, or you broke the logic for
>> enabling NAPI on more than one CPU.
>>
>> I am not sure which is the case, but I think it would be best if you
>> supplied a fixed patch set that corrects whichever happens to be the
>> case.
>
> No, the original logic was already broken. The code assumed that the
> NAPI scheduled by the driver init gets executed always on CPU 0. The
> IRQ got enabled just because we are lucky.

No.  The default affinity for all irqs is CPU0 for just this reason.  So 
there was no luck involved.

>
> The patch removes such assumption. During the driver init, the IRQ is
> disabled and cvm_irq_cpu is -1. So when the NAPI scheduled (on whatever
> CPU) by the init is done, the check in cvm_oct_no_more_work() will be
> false and the IRQ remains disabled. So the init routine has to enable IRQ
> "manually". This is a special case only for the driver initialization.

No.  We schedule NAPI at this point.  If there are no packets available, 
the normal driver logic enables the irq.  There is no need to explicitly 
enable it in cvm_oct_rx_initialize().

If this doesn't work, and you need to have an additional place that you 
enable the irq, then you broke something.


>
> During the normal operation, the IRQ handler record the CPU (on which
> it's going the schedule for the first NAPI poll) in cvm_irq_cpu so
> cvm_oct_no_more_work() will always re-enable the IRQ correctly.
>
> A.
>
>
>

WARNING: multiple messages have this Message-ID (diff)
From: David Daney <ddaney@caviumnetworks.com>
To: Aaro Koskinen <aaro.koskinen@iki.fi>
Cc: devel@driverdev.osuosl.org, linux-mips@linux-mips.org,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	David Daney <david.daney@cavium.com>,
	richard@nod.at
Subject: Re: [PATCH 1/2] staging: octeon-ethernet: don't assume that CPU 0 is special
Date: Mon, 30 Sep 2013 12:41:59 -0700	[thread overview]
Message-ID: <5249D407.2090904@caviumnetworks.com> (raw)
Message-ID: <20130930194159.a2NwvXuwuk2Ic8RYfYyW1TlWp6sgVKWTOaxzlnGKiac@z> (raw)
In-Reply-To: <20130930193502.GE4572@blackmetal.musicnaut.iki.fi>

On 09/30/2013 12:35 PM, Aaro Koskinen wrote:
> Hi,
>
> On Mon, Sep 30, 2013 at 10:23:10AM -0700, David Daney wrote:
>> On 09/28/2013 12:50 PM, Aaro Koskinen wrote:
>>> Currently the driver assumes that CPU 0 is handling all the hard IRQs.
>>> This is wrong in Linux SMP systems where user is allowed to assign to
>>> hardware IRQs to any CPU. The driver will stop working if user sets
>>> smp_affinity so that interrupts end up being handled by other than CPU
>>> 0. The patch fixes that.
>>>
>>> Signed-off-by: Aaro Koskinen <aaro.koskinen@iki.fi>
>>> ---
>>>   drivers/staging/octeon/ethernet-rx.c | 12 ++++++------
>>>   1 file changed, 6 insertions(+), 6 deletions(-)
>>>
>>> diff --git a/drivers/staging/octeon/ethernet-rx.c b/drivers/staging/octeon/ethernet-rx.c
>>> index e14a1bb..de831c1 100644
>>> --- a/drivers/staging/octeon/ethernet-rx.c
>>> +++ b/drivers/staging/octeon/ethernet-rx.c
>>> @@ -80,6 +80,8 @@ struct cvm_oct_core_state {
>>>
>>>   static struct cvm_oct_core_state core_state __cacheline_aligned_in_smp;
>>>
>>> +static int cvm_irq_cpu = -1;
>>> +
>>>   static void cvm_oct_enable_napi(void *_)
>>>   {
>>>   	int cpu = smp_processor_id();
>>> @@ -112,11 +114,7 @@ static void cvm_oct_no_more_work(void)
>>>   {
>>>   	int cpu = smp_processor_id();
>>>
>>> -	/*
>>> -	 * CPU zero is special.  It always has the irq enabled when
>>> -	 * waiting for incoming packets.
>>> -	 */
>>> -	if (cpu == 0) {
>>> +	if (cpu == cvm_irq_cpu) {
>>>   		enable_irq(OCTEON_IRQ_WORKQ0 + pow_receive_group);
>>>   		return;
>>>   	}
>>> @@ -135,6 +133,7 @@ static irqreturn_t cvm_oct_do_interrupt(int cpl, void *dev_id)
>>>   {
>>>   	/* Disable the IRQ and start napi_poll. */
>>>   	disable_irq_nosync(OCTEON_IRQ_WORKQ0 + pow_receive_group);
>>> +	cvm_irq_cpu = smp_processor_id();
>>>   	cvm_oct_enable_napi(NULL);
>>>
>>>   	return IRQ_HANDLED;
>>> @@ -547,8 +546,9 @@ void cvm_oct_rx_initialize(void)
>>>   	cvmx_write_csr(CVMX_POW_WQ_INT_PC, int_pc.u64);
>>>
>>>
>>> -	/* Scheduld NAPI now.  This will indirectly enable interrupts. */
>>> +	/* Schedule NAPI now. */
>>>   	cvm_oct_enable_one_cpu();
>>> +	enable_irq(OCTEON_IRQ_WORKQ0 + pow_receive_group);
>>
>> The fact that you have to manually enable irqs here indicates that
>> the patch is not good.
>>
>> Either the enable_irq() is unnecessary, or you broke the logic for
>> enabling NAPI on more than one CPU.
>>
>> I am not sure which is the case, but I think it would be best if you
>> supplied a fixed patch set that corrects whichever happens to be the
>> case.
>
> No, the original logic was already broken. The code assumed that the
> NAPI scheduled by the driver init gets executed always on CPU 0. The
> IRQ got enabled just because we are lucky.

No.  The default affinity for all irqs is CPU0 for just this reason.  So 
there was no luck involved.

>
> The patch removes such assumption. During the driver init, the IRQ is
> disabled and cvm_irq_cpu is -1. So when the NAPI scheduled (on whatever
> CPU) by the init is done, the check in cvm_oct_no_more_work() will be
> false and the IRQ remains disabled. So the init routine has to enable IRQ
> "manually". This is a special case only for the driver initialization.

No.  We schedule NAPI at this point.  If there are no packets available, 
the normal driver logic enables the irq.  There is no need to explicitly 
enable it in cvm_oct_rx_initialize().

If this doesn't work, and you need to have an additional place that you 
enable the irq, then you broke something.


>
> During the normal operation, the IRQ handler record the CPU (on which
> it's going the schedule for the first NAPI poll) in cvm_irq_cpu so
> cvm_oct_no_more_work() will always re-enable the IRQ correctly.
>
> A.
>
>
>

  reply	other threads:[~2013-09-30 19:42 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-09-28 19:50 [PATCH 1/2] staging: octeon-ethernet: don't assume that CPU 0 is special Aaro Koskinen
2013-09-28 19:50 ` [PATCH 2/2] staging: octeon-ethernet: allow to use only 1 CPU for packet processing Aaro Koskinen
2013-09-28 20:40 ` [PATCH 1/2] staging: octeon-ethernet: don't assume that CPU 0 is special Richard Weinberger
2013-09-28 21:12   ` Aaro Koskinen
2013-09-28 21:15 ` Richard Weinberger
2013-09-30 17:23 ` David Daney
2013-09-30 17:23   ` David Daney
2013-09-30 19:35   ` Aaro Koskinen
2013-09-30 19:41     ` David Daney [this message]
2013-09-30 19:41       ` David Daney
2013-09-30 19:56       ` Aaro Koskinen
2013-09-30 21:08         ` David Daney
2013-09-30 21:08           ` David Daney
2013-09-30 21:27           ` Aaro Koskinen
2013-10-03 20:36 ` Greg Kroah-Hartman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5249D407.2090904@caviumnetworks.com \
    --to=ddaney@caviumnetworks.com \
    --cc=aaro.koskinen@iki.fi \
    --cc=david.daney@cavium.com \
    --cc=devel@driverdev.osuosl.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=linux-mips@linux-mips.org \
    --cc=richard@nod.at \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.