diff mbox series

[net-next] rocker: Postpone filtering of !added_by_user FDB

Message ID 6fbb39711485d7abbe7cdaa8042a222b9588a6b6.1525957759.git.petrm@mellanox.com
State Accepted, archived
Delegated to: David Miller
Headers show
Series [net-next] rocker: Postpone filtering of !added_by_user FDB | expand

Commit Message

Petr Machata May 10, 2018, 1:29 p.m. UTC
Breaking out of the switch in rocker_switchdev_event() still ends up
scheduling work, except an ill-defined one. This leads to an OOPS cited
below. Fix by postponing the check until rocker_switchdev_event_work().

[   23.148476] BUG: unable to handle kernel NULL pointer dereference at 0000000000000000
[   23.148810] PGD 0 P4D 0
[   23.148982] Oops: 0000 [#1] PREEMPT SMP PTI
[   23.149190] Modules linked in: bridge stp llc iptable_nat nf_nat_ipv4 nf_nat e1000 rocker
[   23.149768] CPU: 0 PID: 239 Comm: kworker/u2:4 Not tainted 4.17.0-rc3-net_next_queue-custom #6
[   23.150298] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-2.fc27 04/01/2014
[   23.150868] Workqueue: rocker rocker_switchdev_event_work [rocker]
[   23.151258] RIP: 0010:ofdpa_port_fdb+0x7b/0x230 [rocker]
[   23.151597] RSP: 0018:ffffc900004b3e18 EFLAGS: 00010246
[   23.151952] RAX: 00000000fffbc68c RBX: 0000000000000000 RCX: 0000000000000000
[   23.152363] RDX: 0000000000000010 RSI: ffff88003b4471e0 RDI: 00000000ffffffff
[   23.152768] RBP: ffff88003b4471c0 R08: ffff88003b4471e0 R09: ffff88003b4471c0
[   23.153141] R10: 0000000000000000 R11: 0000000000000000 R12: ffff880036caf000
[   23.153515] R13: 0000000000000000 R14: 0000000000000000 R15: ffff88003bc00000
[   23.153919] FS:  0000000000000000(0000) GS:ffff88003fc00000(0000) knlGS:0000000000000000
[   23.154444] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[   23.154806] CR2: 0000000000000000 CR3: 0000000036eb6000 CR4: 00000000000006f0
[   23.155194] Call Trace:
[   23.155472]  rocker_switchdev_event_work+0x9b/0xd0 [rocker]
[   23.155850]  ? __schedule+0x231/0x700
[   23.156175]  process_one_work+0x1cf/0x3e0
[   23.156490]  worker_thread+0x26/0x3d0
[   23.156795]  ? trace_event_raw_event_workqueue_execute_start+0x80/0x80
[   23.157181]  kthread+0x10e/0x130
[   23.157485]  ? kthread_create_worker_on_cpu+0x40/0x40
[   23.157824]  ret_from_fork+0x35/0x40
[   23.158174] Code: 00 00 c1 e8 02 4c 8d 45 20 bf ff ff ff ff 83 e0 01 4c 89 65 20 88 45 14 48 8b 05 21 da 1f e2 4c 89 c6 4c 89 44 24 10 48 89 45 18 <41> 8b 45 00 89 45 28 41 0f b7 45 04 66 89 45 2c 0f b7 44 24 04
[   23.159346] RIP: ofdpa_port_fdb+0x7b/0x230 [rocker] RSP: ffffc900004b3e18
[   23.159742] CR2: 0000000000000000
[   23.160088] ---[ end trace f9b16d4cb6df0629 ]---

Fixes: 816a3bed9549 ("switchdev: Add fdb.added_by_user to switchdev notifications")
Suggested-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
Signed-off-by: Petr Machata <petrm@mellanox.com>
---
 drivers/net/ethernet/rocker/rocker_main.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

Comments

Vivien Didelot May 10, 2018, 2:21 p.m. UTC | #1
Petr Machata <petrm@mellanox.com> writes:

> Breaking out of the switch in rocker_switchdev_event() still ends up
> scheduling work, except an ill-defined one. This leads to an OOPS cited
> below. Fix by postponing the check until rocker_switchdev_event_work().
>
> [   23.148476] BUG: unable to handle kernel NULL pointer dereference at 0000000000000000
> [   23.148810] PGD 0 P4D 0
> [   23.148982] Oops: 0000 [#1] PREEMPT SMP PTI
> [   23.149190] Modules linked in: bridge stp llc iptable_nat nf_nat_ipv4 nf_nat e1000 rocker
> [   23.149768] CPU: 0 PID: 239 Comm: kworker/u2:4 Not tainted 4.17.0-rc3-net_next_queue-custom #6
> [   23.150298] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-2.fc27 04/01/2014
> [   23.150868] Workqueue: rocker rocker_switchdev_event_work [rocker]
> [   23.151258] RIP: 0010:ofdpa_port_fdb+0x7b/0x230 [rocker]
> [   23.151597] RSP: 0018:ffffc900004b3e18 EFLAGS: 00010246
> [   23.151952] RAX: 00000000fffbc68c RBX: 0000000000000000 RCX: 0000000000000000
> [   23.152363] RDX: 0000000000000010 RSI: ffff88003b4471e0 RDI: 00000000ffffffff
> [   23.152768] RBP: ffff88003b4471c0 R08: ffff88003b4471e0 R09: ffff88003b4471c0
> [   23.153141] R10: 0000000000000000 R11: 0000000000000000 R12: ffff880036caf000
> [   23.153515] R13: 0000000000000000 R14: 0000000000000000 R15: ffff88003bc00000
> [   23.153919] FS:  0000000000000000(0000) GS:ffff88003fc00000(0000) knlGS:0000000000000000
> [   23.154444] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> [   23.154806] CR2: 0000000000000000 CR3: 0000000036eb6000 CR4: 00000000000006f0
> [   23.155194] Call Trace:
> [   23.155472]  rocker_switchdev_event_work+0x9b/0xd0 [rocker]
> [   23.155850]  ? __schedule+0x231/0x700
> [   23.156175]  process_one_work+0x1cf/0x3e0
> [   23.156490]  worker_thread+0x26/0x3d0
> [   23.156795]  ? trace_event_raw_event_workqueue_execute_start+0x80/0x80
> [   23.157181]  kthread+0x10e/0x130
> [   23.157485]  ? kthread_create_worker_on_cpu+0x40/0x40
> [   23.157824]  ret_from_fork+0x35/0x40
> [   23.158174] Code: 00 00 c1 e8 02 4c 8d 45 20 bf ff ff ff ff 83 e0 01 4c 89 65 20 88 45 14 48 8b 05 21 da 1f e2 4c 89 c6 4c 89 44 24 10 48 89 45 18 <41> 8b 45 00 89 45 28 41 0f b7 45 04 66 89 45 2c 0f b7 44 24 04
> [   23.159346] RIP: ofdpa_port_fdb+0x7b/0x230 [rocker] RSP: ffffc900004b3e18
> [   23.159742] CR2: 0000000000000000
> [   23.160088] ---[ end trace f9b16d4cb6df0629 ]---
>
> Fixes: 816a3bed9549 ("switchdev: Add fdb.added_by_user to switchdev notifications")
> Suggested-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
> Signed-off-by: Petr Machata <petrm@mellanox.com>

Reviewed-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
David Miller May 10, 2018, 9:55 p.m. UTC | #2
From: Petr Machata <petrm@mellanox.com>
Date: Thu, 10 May 2018 15:29:46 +0200

> Breaking out of the switch in rocker_switchdev_event() still ends up
> scheduling work, except an ill-defined one. This leads to an OOPS cited
> below. Fix by postponing the check until rocker_switchdev_event_work().
 ...
> Fixes: 816a3bed9549 ("switchdev: Add fdb.added_by_user to switchdev notifications")
> Suggested-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
> Signed-off-by: Petr Machata <petrm@mellanox.com>

Applied.
diff mbox series

Patch

diff --git a/drivers/net/ethernet/rocker/rocker_main.c b/drivers/net/ethernet/rocker/rocker_main.c
index 152d694..e73e4fe 100644
--- a/drivers/net/ethernet/rocker/rocker_main.c
+++ b/drivers/net/ethernet/rocker/rocker_main.c
@@ -2738,6 +2738,8 @@  static void rocker_switchdev_event_work(struct work_struct *work)
 	switch (switchdev_work->event) {
 	case SWITCHDEV_FDB_ADD_TO_DEVICE:
 		fdb_info = &switchdev_work->fdb_info;
+		if (!fdb_info->added_by_user)
+			break;
 		err = rocker_world_port_fdb_add(rocker_port, fdb_info);
 		if (err) {
 			netdev_dbg(rocker_port->dev, "fdb add failed err=%d\n", err);
@@ -2747,6 +2749,8 @@  static void rocker_switchdev_event_work(struct work_struct *work)
 		break;
 	case SWITCHDEV_FDB_DEL_TO_DEVICE:
 		fdb_info = &switchdev_work->fdb_info;
+		if (!fdb_info->added_by_user)
+			break;
 		err = rocker_world_port_fdb_del(rocker_port, fdb_info);
 		if (err)
 			netdev_dbg(rocker_port->dev, "fdb add failed err=%d\n", err);
@@ -2783,8 +2787,6 @@  static int rocker_switchdev_event(struct notifier_block *unused,
 	switch (event) {
 	case SWITCHDEV_FDB_ADD_TO_DEVICE: /* fall through */
 	case SWITCHDEV_FDB_DEL_TO_DEVICE:
-		if (!fdb_info->added_by_user)
-			break;
 		memcpy(&switchdev_work->fdb_info, ptr,
 		       sizeof(switchdev_work->fdb_info));
 		switchdev_work->fdb_info.addr = kzalloc(ETH_ALEN, GFP_ATOMIC);