linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Marc Zyngier <marc.zyngier@arm.com>
To: Antoine Tenart <antoine.tenart@bootlin.com>
Cc: davem@davemloft.net, netdev@vger.kernel.org,
	linux-kernel@vger.kernel.org, thomas.petazzoni@bootlin.com,
	maxime.chevallier@bootlin.com, gregory.clement@bootlin.com,
	miquel.raynal@bootlin.com, nadavh@marvell.com,
	stefanc@marvell.com, ymarkman@marvell.com, mw@semihalf.com
Subject: Re: [PATCH net-next 11/12] net: mvpp2: handle cases where more CPUs are available than s/w threads
Date: Mon, 29 Oct 2018 17:35:52 +0000	[thread overview]
Message-ID: <a3108c92-37b8-996e-01f6-72b7db532570@arm.com> (raw)
In-Reply-To: <20180919092711.22296-12-antoine.tenart@bootlin.com>

Antoine,

On 19/09/18 10:27, Antoine Tenart wrote:
> The Marvell PPv2 network controller has 9 internal threads. The driver
> works fine when there are less CPUs available than threads. This isn't
> true if more CPUs are available. As this is a valid use case, handle
> this particular case.
> 
> Signed-off-by: Antoine Tenart <antoine.tenart@bootlin.com>
> ---
>  drivers/net/ethernet/marvell/mvpp2/mvpp2.h    |  14 +-
>  .../net/ethernet/marvell/mvpp2/mvpp2_main.c   | 152 ++++++++++++------
>  2 files changed, 112 insertions(+), 54 deletions(-)

[...]

> @@ -3270,9 +3299,18 @@ static int mvpp2_irqs_init(struct mvpp2_port *port)
>  		if (err)
>  			goto err;
>  
> -		if (qv->type == MVPP2_QUEUE_VECTOR_PRIVATE)
> -			irq_set_affinity_hint(qv->irq,
> -					      cpumask_of(qv->sw_thread_id));
> +		if (qv->type == MVPP2_QUEUE_VECTOR_PRIVATE) {
> +			unsigned long mask = 0;
> +			unsigned int cpu;
> +
> +			for_each_present_cpu(cpu) {
> +				if (mvpp2_cpu_to_thread(port->priv, cpu) ==
> +				    qv->sw_thread_id)
> +					mask |= BIT(cpu);
> +			}
> +
> +			irq_set_affinity_hint(qv->irq, to_cpumask(&mask));
> +		}

Really??? How on Earth are you testing this code?

I'll paper over the implicit limitation to 64 CPUs and the open-coded
version of cpumask_set_cpu(). But the to_cpumask on a local variable
passed to the core IRQ code?

All it takes is to boot the box with a non-trivial distro, and here she 
goes:

[   11.779309] Unable to handle kernel paging request at virtual address ffff00000e8db278
[   11.779310] Mem abort info:
[   11.779311]   ESR = 0x96000007
[   11.779313]   Exception class = DABT (current EL), IL = 32 bits
[   11.779314]   SET = 0, FnV = 0
[   11.779315]   EA = 0, S1PTW = 0
[   11.779316] Data abort info:
[   11.779317]   ISV = 0, ISS = 0x00000007
[   11.779319]   CM = 0, WnR = 0
[   11.779321] swapper pgtable: 4k pages, 48-bit VAs, pgdp = 0000000092e8dfda
[   11.779322] [ffff00000e8db278] pgd=00000000effff803, pud=00000000efffe803, pmd=00000000e6795003, pte=0000000000000000
[   11.779328] Internal error: Oops: 96000007 [#1] PREEMPT SMP
[   11.779329] Modules linked in:
[   11.779334] CPU: 1 PID: 2952 Comm: irqbalance Not tainted 4.19.0-09418-g9f51ae62c84a-dirty #273
[   11.779336] Hardware name: Marvell 8040 MACCHIATOBin (DT)
[   11.779338] pstate: 40000085 (nZcv daIf -PAN -UAO)
[   11.779346] pc : irq_affinity_hint_proc_show+0x64/0xc0
[   11.779349] lr : irq_affinity_hint_proc_show+0x5c/0xc0
[   11.779350] sp : ffff00000e97bc70
[   11.779351] x29: ffff00000e97bc70 x28: 0000aaab12101290 
[   11.779354] x27: ffff8000e6ac6b40 x26: 0000000000000400 
[   11.779356] x25: ffff8000e80dd100 x24: ffff00000e97be60 
[   11.779358] x23: 00000000007000c0 x22: ffff8000e80272a4 
[   11.779360] x21: ffff8000e6ac6b00 x20: ffff8000e8027200 
[   11.779362] x19: ffff0000093596c8 x18: ffff000009371000 
[   11.779364] x17: 0000000000000000 x16: 0000000000000000 
[   11.779366] x15: 00000000fffffff0 x14: ffff0000094c3b62 
[   11.779368] x13: 0000000000000000 x12: ffff0000094c3000 
[   11.779370] x11: ffff000009371000 x10: ffff0000094c31b0 
[   11.779372] x9 : 0000000000000000 x8 : ffff0000094cd77b 
[   11.779374] x7 : 0000000000000000 x6 : 000000001c96d97e 
[   11.779376] x5 : 0000000000000000 x4 : ffff8000eff850b0 
[   11.779378] x3 : ffff8000e80272a4 x2 : ffff00000e8db278 
[   11.779380] x1 : 0000000000000000 x0 : 0000000000000000 
[   11.779383] Process irqbalance (pid: 2952, stack limit = 0x000000002121ca97)
[   11.779385] Call trace:
[   11.779387]  irq_affinity_hint_proc_show+0x64/0xc0
[   11.779391]  seq_read+0x130/0x448
[   11.779394]  proc_reg_read+0x6c/0xa8
[   11.779397]  __vfs_read+0x30/0x148
[   11.779398]  vfs_read+0x8c/0x160
[   11.779400]  ksys_read+0x5c/0xc0
[   11.779401]  __arm64_sys_read+0x18/0x20
[   11.779405]  el0_svc_common+0x84/0xd8
[   11.779407]  el0_svc_handler+0x2c/0x80
[   11.779410]  el0_svc+0x8/0xc
[   11.779412] Code: aa1603e0 942650d4 f9405e82 b4000062 (f9400041) 
[   11.779415] ---[ end trace 8648ea6a05ca014e ]---
[   11.779418] note: irqbalance[2952] exited with preempt_count 1

After that, the box is wedged.

I came up with the following fix, which fixes the issue for me.

Thanks,

	M.

From ca25785bd1a679e72ed77e939b19360bfd0eecea Mon Sep 17 00:00:00 2001
From: Marc Zyngier <marc.zyngier@arm.com>
Date: Mon, 29 Oct 2018 17:07:25 +0000
Subject: [PATCH] net: mvpp2: Fix affinity hint allocation

The mvpp2 driver has the curious behaviour of passing a stack variable
to irq_set_affinity_hint(), which results in the kernel exploding
the first time anyone accesses this information. News flash: userspace
does, and irqbalance will happily take the machine down. Great stuff.

An easy fix is to track the mask within the queue_vector structure,
and to make sure it has the same lifetime as the interrupt itself.

Fixes: e531f76757eb ("net: mvpp2: handle cases where more CPUs are available than s/w threads")
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 drivers/net/ethernet/marvell/mvpp2/mvpp2.h     |  1 +
 .../net/ethernet/marvell/mvpp2/mvpp2_main.c    | 18 ++++++++++++++----
 2 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2.h b/drivers/net/ethernet/marvell/mvpp2/mvpp2.h
index 176c6b56fdcc..398328f10743 100644
--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2.h
+++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2.h
@@ -796,6 +796,7 @@ struct mvpp2_queue_vector {
 	int nrxqs;
 	u32 pending_cause_rx;
 	struct mvpp2_port *port;
+	struct cpumask *mask;
 };
 
 struct mvpp2_port {
diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
index 14f9679c957c..7a37a37e3fb3 100644
--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
@@ -3298,24 +3298,30 @@ static int mvpp2_irqs_init(struct mvpp2_port *port)
 	for (i = 0; i < port->nqvecs; i++) {
 		struct mvpp2_queue_vector *qv = port->qvecs + i;
 
-		if (qv->type == MVPP2_QUEUE_VECTOR_PRIVATE)
+		if (qv->type == MVPP2_QUEUE_VECTOR_PRIVATE) {
+			qv->mask = kzalloc(cpumask_size(), GFP_KERNEL);
+			if (!qv->mask) {
+				err = -ENOMEM;
+				goto err;
+			}
+
 			irq_set_status_flags(qv->irq, IRQ_NO_BALANCING);
+		}
 
 		err = request_irq(qv->irq, mvpp2_isr, 0, port->dev->name, qv);
 		if (err)
 			goto err;
 
 		if (qv->type == MVPP2_QUEUE_VECTOR_PRIVATE) {
-			unsigned long mask = 0;
 			unsigned int cpu;
 
 			for_each_present_cpu(cpu) {
 				if (mvpp2_cpu_to_thread(port->priv, cpu) ==
 				    qv->sw_thread_id)
-					mask |= BIT(cpu);
+					cpumask_set_cpu(cpu, qv->mask);
 			}
 
-			irq_set_affinity_hint(qv->irq, to_cpumask(&mask));
+			irq_set_affinity_hint(qv->irq, qv->mask);
 		}
 	}
 
@@ -3325,6 +3331,8 @@ static int mvpp2_irqs_init(struct mvpp2_port *port)
 		struct mvpp2_queue_vector *qv = port->qvecs + i;
 
 		irq_set_affinity_hint(qv->irq, NULL);
+		kfree(qv->mask);
+		qv->mask = NULL;
 		free_irq(qv->irq, qv);
 	}
 
@@ -3339,6 +3347,8 @@ static void mvpp2_irqs_deinit(struct mvpp2_port *port)
 		struct mvpp2_queue_vector *qv = port->qvecs + i;
 
 		irq_set_affinity_hint(qv->irq, NULL);
+		kfree(qv->mask);
+		qv->mask = NULL;
 		irq_clear_status_flags(qv->irq, IRQ_NO_BALANCING);
 		free_irq(qv->irq, qv);
 	}
-- 
2.19.1


-- 
Jazz is not dead. It just smells funny...

  reply	other threads:[~2018-10-29 17:35 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-09-19  9:26 [PATCH net-next 00/12] net: mvpp2: improve the interrupt usage Antoine Tenart
2018-09-19  9:27 ` [PATCH net-next 01/12] net: mvpp2: increase the number of s/w threads to 9 Antoine Tenart
2018-09-19  9:27 ` [PATCH net-next 02/12] net: mvpp2: rename the IRQs to match the hardware Antoine Tenart
2018-09-19  9:27 ` [PATCH net-next 03/12] Documentation/bindings: net: marvell-pp2: update the IRQs description Antoine Tenart
2018-09-19  9:27 ` [PATCH net-next 04/12] net: mvpp2: do not update the queue mode while probing Antoine Tenart
2018-09-19  9:27 ` [PATCH net-next 05/12] net: mvpp2: fix the number of queues per cpu for PPv2.2 Antoine Tenart
2018-09-19  9:27 ` [PATCH net-next 06/12] net: mvpp2: cpu should always be unsigned Antoine Tenart
2018-09-19  9:27 ` [PATCH net-next 07/12] net: mvpp2: make the per-cpu helpers static Antoine Tenart
2018-09-19  9:27 ` [PATCH net-next 08/12] net: mvpp2: make mvpp2_read_relaxed static Antoine Tenart
2018-09-19  9:27 ` [PATCH net-next 09/12] net: mvpp2: do not use the CPU number to access the per-thread registers Antoine Tenart
2018-09-19  9:27 ` [PATCH net-next 10/12] net: mvpp2: map the CPUs to threads Antoine Tenart
2018-09-19  9:27 ` [PATCH net-next 11/12] net: mvpp2: handle cases where more CPUs are available than s/w threads Antoine Tenart
2018-10-29 17:35   ` Marc Zyngier [this message]
2018-10-30 13:53     ` Antoine Tenart
2018-09-19  9:27 ` [PATCH net-next 12/12] net: mvpp2: rename mvpp2_percpu function to mvpp2_thread Antoine Tenart
2018-09-20  4:13 ` [PATCH net-next 00/12] net: mvpp2: improve the interrupt usage David Miller

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=a3108c92-37b8-996e-01f6-72b7db532570@arm.com \
    --to=marc.zyngier@arm.com \
    --cc=antoine.tenart@bootlin.com \
    --cc=davem@davemloft.net \
    --cc=gregory.clement@bootlin.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=maxime.chevallier@bootlin.com \
    --cc=miquel.raynal@bootlin.com \
    --cc=mw@semihalf.com \
    --cc=nadavh@marvell.com \
    --cc=netdev@vger.kernel.org \
    --cc=stefanc@marvell.com \
    --cc=thomas.petazzoni@bootlin.com \
    --cc=ymarkman@marvell.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).