From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: stable@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
patches@lists.linux.dev,
"Ahmed S. Darwish" <a.darwish@linutronix.de>,
Sebastian Andrzej Siewior <bigeasy@linutronix.de>,
Jakub Kicinski <kuba@kernel.org>, Sasha Levin <sashal@kernel.org>
Subject: [PATCH 5.4 19/67] net: arcnet: Fix RESET flag handling
Date: Mon, 11 Dec 2023 19:22:03 +0100 [thread overview]
Message-ID: <20231211182015.914777215@linuxfoundation.org> (raw)
In-Reply-To: <20231211182015.049134368@linuxfoundation.org>
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ahmed S. Darwish <a.darwish@linutronix.de>
[ Upstream commit 01365633bd1c836240f9bbf86bbeee749795480a ]
The main arcnet interrupt handler calls arcnet_close() then
arcnet_open(), if the RESET status flag is encountered.
This is invalid:
1) In general, interrupt handlers should never call ->ndo_stop() and
->ndo_open() functions. They are usually full of blocking calls and
other methods that are expected to be called only from drivers
init and exit code paths.
2) arcnet_close() contains a del_timer_sync(). If the irq handler
interrupts the to-be-deleted timer, del_timer_sync() will just loop
forever.
3) arcnet_close() also calls tasklet_kill(), which has a warning if
called from irq context.
4) For device reset, the sequence "arcnet_close(); arcnet_open();" is
not complete. Some children arcnet drivers have special init/exit
code sequences, which then embed a call to arcnet_open() and
arcnet_close() accordingly. Check drivers/net/arcnet/com20020.c.
Run the device RESET sequence from a scheduled workqueue instead.
Signed-off-by: Ahmed S. Darwish <a.darwish@linutronix.de>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Link: https://lore.kernel.org/r/20210128194802.727770-1-a.darwish@linutronix.de
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Stable-dep-of: 6b17a597fc2f ("arcnet: restoring support for multiple Sohard Arcnet cards")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/arcnet/arc-rimi.c | 4 +-
drivers/net/arcnet/arcdevice.h | 6 +++
drivers/net/arcnet/arcnet.c | 66 +++++++++++++++++++++++++++++--
drivers/net/arcnet/com20020-isa.c | 4 +-
drivers/net/arcnet/com20020-pci.c | 2 +-
drivers/net/arcnet/com20020_cs.c | 2 +-
drivers/net/arcnet/com90io.c | 4 +-
drivers/net/arcnet/com90xx.c | 4 +-
8 files changed, 78 insertions(+), 14 deletions(-)
diff --git a/drivers/net/arcnet/arc-rimi.c b/drivers/net/arcnet/arc-rimi.c
index 14a5fb3781453..313b636edf239 100644
--- a/drivers/net/arcnet/arc-rimi.c
+++ b/drivers/net/arcnet/arc-rimi.c
@@ -332,7 +332,7 @@ static int __init arc_rimi_init(void)
dev->irq = 9;
if (arcrimi_probe(dev)) {
- free_netdev(dev);
+ free_arcdev(dev);
return -EIO;
}
@@ -349,7 +349,7 @@ static void __exit arc_rimi_exit(void)
iounmap(lp->mem_start);
release_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1);
free_irq(dev->irq, dev);
- free_netdev(dev);
+ free_arcdev(dev);
}
#ifndef MODULE
diff --git a/drivers/net/arcnet/arcdevice.h b/drivers/net/arcnet/arcdevice.h
index b0f5bc07aef5b..7178f5349fa8f 100644
--- a/drivers/net/arcnet/arcdevice.h
+++ b/drivers/net/arcnet/arcdevice.h
@@ -298,6 +298,10 @@ struct arcnet_local {
int excnak_pending; /* We just got an excesive nak interrupt */
+ /* RESET flag handling */
+ int reset_in_progress;
+ struct work_struct reset_work;
+
struct {
uint16_t sequence; /* sequence number (incs with each packet) */
__be16 aborted_seq;
@@ -350,7 +354,9 @@ void arcnet_dump_skb(struct net_device *dev, struct sk_buff *skb, char *desc)
void arcnet_unregister_proto(struct ArcProto *proto);
irqreturn_t arcnet_interrupt(int irq, void *dev_id);
+
struct net_device *alloc_arcdev(const char *name);
+void free_arcdev(struct net_device *dev);
int arcnet_open(struct net_device *dev);
int arcnet_close(struct net_device *dev);
diff --git a/drivers/net/arcnet/arcnet.c b/drivers/net/arcnet/arcnet.c
index 2b112d3d85409..cf652c76af85e 100644
--- a/drivers/net/arcnet/arcnet.c
+++ b/drivers/net/arcnet/arcnet.c
@@ -387,10 +387,44 @@ static void arcnet_timer(struct timer_list *t)
struct arcnet_local *lp = from_timer(lp, t, timer);
struct net_device *dev = lp->dev;
- if (!netif_carrier_ok(dev)) {
+ spin_lock_irq(&lp->lock);
+
+ if (!lp->reset_in_progress && !netif_carrier_ok(dev)) {
netif_carrier_on(dev);
netdev_info(dev, "link up\n");
}
+
+ spin_unlock_irq(&lp->lock);
+}
+
+static void reset_device_work(struct work_struct *work)
+{
+ struct arcnet_local *lp;
+ struct net_device *dev;
+
+ lp = container_of(work, struct arcnet_local, reset_work);
+ dev = lp->dev;
+
+ /* Do not bring the network interface back up if an ifdown
+ * was already done.
+ */
+ if (!netif_running(dev) || !lp->reset_in_progress)
+ return;
+
+ rtnl_lock();
+
+ /* Do another check, in case of an ifdown that was triggered in
+ * the small race window between the exit condition above and
+ * acquiring RTNL.
+ */
+ if (!netif_running(dev) || !lp->reset_in_progress)
+ goto out;
+
+ dev_close(dev);
+ dev_open(dev, NULL);
+
+out:
+ rtnl_unlock();
}
static void arcnet_reply_tasklet(unsigned long data)
@@ -452,12 +486,25 @@ struct net_device *alloc_arcdev(const char *name)
lp->dev = dev;
spin_lock_init(&lp->lock);
timer_setup(&lp->timer, arcnet_timer, 0);
+ INIT_WORK(&lp->reset_work, reset_device_work);
}
return dev;
}
EXPORT_SYMBOL(alloc_arcdev);
+void free_arcdev(struct net_device *dev)
+{
+ struct arcnet_local *lp = netdev_priv(dev);
+
+ /* Do not cancel this at ->ndo_close(), as the workqueue itself
+ * indirectly calls the ifdown path through dev_close().
+ */
+ cancel_work_sync(&lp->reset_work);
+ free_netdev(dev);
+}
+EXPORT_SYMBOL(free_arcdev);
+
/* Open/initialize the board. This is called sometime after booting when
* the 'ifconfig' program is run.
*
@@ -587,6 +634,10 @@ int arcnet_close(struct net_device *dev)
/* shut down the card */
lp->hw.close(dev);
+
+ /* reset counters */
+ lp->reset_in_progress = 0;
+
module_put(lp->hw.owner);
return 0;
}
@@ -820,6 +871,9 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id)
spin_lock_irqsave(&lp->lock, flags);
+ if (lp->reset_in_progress)
+ goto out;
+
/* RESET flag was enabled - if device is not running, we must
* clear it right away (but nothing else).
*/
@@ -852,11 +906,14 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id)
if (status & RESETflag) {
arc_printk(D_NORMAL, dev, "spurious reset (status=%Xh)\n",
status);
- arcnet_close(dev);
- arcnet_open(dev);
+
+ lp->reset_in_progress = 1;
+ netif_stop_queue(dev);
+ netif_carrier_off(dev);
+ schedule_work(&lp->reset_work);
/* get out of the interrupt handler! */
- break;
+ goto out;
}
/* RX is inhibited - we must have received something.
* Prepare to receive into the next buffer.
@@ -1052,6 +1109,7 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id)
udelay(1);
lp->hw.intmask(dev, lp->intmask);
+out:
spin_unlock_irqrestore(&lp->lock, flags);
return retval;
}
diff --git a/drivers/net/arcnet/com20020-isa.c b/drivers/net/arcnet/com20020-isa.c
index cd27fdc1059b9..141b05451252e 100644
--- a/drivers/net/arcnet/com20020-isa.c
+++ b/drivers/net/arcnet/com20020-isa.c
@@ -169,7 +169,7 @@ static int __init com20020_init(void)
dev->irq = 9;
if (com20020isa_probe(dev)) {
- free_netdev(dev);
+ free_arcdev(dev);
return -EIO;
}
@@ -182,7 +182,7 @@ static void __exit com20020_exit(void)
unregister_netdev(my_dev);
free_irq(my_dev->irq, my_dev);
release_region(my_dev->base_addr, ARCNET_TOTAL_SIZE);
- free_netdev(my_dev);
+ free_arcdev(my_dev);
}
#ifndef MODULE
diff --git a/drivers/net/arcnet/com20020-pci.c b/drivers/net/arcnet/com20020-pci.c
index 9f44e2e458df1..b4f8798d8c509 100644
--- a/drivers/net/arcnet/com20020-pci.c
+++ b/drivers/net/arcnet/com20020-pci.c
@@ -294,7 +294,7 @@ static void com20020pci_remove(struct pci_dev *pdev)
unregister_netdev(dev);
free_irq(dev->irq, dev);
- free_netdev(dev);
+ free_arcdev(dev);
}
}
diff --git a/drivers/net/arcnet/com20020_cs.c b/drivers/net/arcnet/com20020_cs.c
index cf607ffcf358e..9cc5eb6a8e905 100644
--- a/drivers/net/arcnet/com20020_cs.c
+++ b/drivers/net/arcnet/com20020_cs.c
@@ -177,7 +177,7 @@ static void com20020_detach(struct pcmcia_device *link)
dev = info->dev;
if (dev) {
dev_dbg(&link->dev, "kfree...\n");
- free_netdev(dev);
+ free_arcdev(dev);
}
dev_dbg(&link->dev, "kfree2...\n");
kfree(info);
diff --git a/drivers/net/arcnet/com90io.c b/drivers/net/arcnet/com90io.c
index 186bbf87bc849..5843b8976fd19 100644
--- a/drivers/net/arcnet/com90io.c
+++ b/drivers/net/arcnet/com90io.c
@@ -396,7 +396,7 @@ static int __init com90io_init(void)
err = com90io_probe(dev);
if (err) {
- free_netdev(dev);
+ free_arcdev(dev);
return err;
}
@@ -419,7 +419,7 @@ static void __exit com90io_exit(void)
free_irq(dev->irq, dev);
release_region(dev->base_addr, ARCNET_TOTAL_SIZE);
- free_netdev(dev);
+ free_arcdev(dev);
}
module_init(com90io_init)
diff --git a/drivers/net/arcnet/com90xx.c b/drivers/net/arcnet/com90xx.c
index bd75d06ad7dfc..5e40ecf189b15 100644
--- a/drivers/net/arcnet/com90xx.c
+++ b/drivers/net/arcnet/com90xx.c
@@ -554,7 +554,7 @@ static int __init com90xx_found(int ioaddr, int airq, u_long shmem,
err_release_mem:
release_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1);
err_free_dev:
- free_netdev(dev);
+ free_arcdev(dev);
return -EIO;
}
@@ -672,7 +672,7 @@ static void __exit com90xx_exit(void)
release_region(dev->base_addr, ARCNET_TOTAL_SIZE);
release_mem_region(dev->mem_start,
dev->mem_end - dev->mem_start + 1);
- free_netdev(dev);
+ free_arcdev(dev);
}
}
--
2.42.0
next prev parent reply other threads:[~2023-12-11 18:42 UTC|newest]
Thread overview: 74+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-12-11 18:21 [PATCH 5.4 00/67] 5.4.264-rc1 review Greg Kroah-Hartman
2023-12-11 18:21 ` [PATCH 5.4 01/67] hrtimers: Push pending hrtimers away from outgoing CPU earlier Greg Kroah-Hartman
2023-12-11 18:21 ` [PATCH 5.4 02/67] netfilter: ipset: fix race condition between swap/destroy and kernel side add/del/test Greg Kroah-Hartman
2023-12-11 18:21 ` [PATCH 5.4 03/67] tg3: Move the [rt]x_dropped counters to tg3_napi Greg Kroah-Hartman
2023-12-11 18:21 ` [PATCH 5.4 04/67] tg3: Increment tx_dropped in tg3_tso_bug() Greg Kroah-Hartman
2023-12-11 18:21 ` [PATCH 5.4 05/67] kconfig: fix memory leak from range properties Greg Kroah-Hartman
2023-12-11 18:21 ` [PATCH 5.4 06/67] drm/amdgpu: correct chunk_ptr to a pointer to chunk Greg Kroah-Hartman
2023-12-11 18:21 ` [PATCH 5.4 07/67] of: base: Add of_get_cpu_state_node() to get idle states for a CPU node Greg Kroah-Hartman
2023-12-11 18:21 ` [PATCH 5.4 08/67] ACPI/IORT: Make iort_get_device_domain IRQ domain agnostic Greg Kroah-Hartman
2023-12-11 18:21 ` [PATCH 5.4 09/67] ACPI/IORT: Make iort_msi_map_rid() PCI agnostic Greg Kroah-Hartman
2023-12-11 18:21 ` [PATCH 5.4 10/67] of/iommu: Make of_map_rid() " Greg Kroah-Hartman
2023-12-11 18:21 ` [PATCH 5.4 11/67] of/irq: make of_msi_map_get_device_domain() bus agnostic Greg Kroah-Hartman
2023-12-11 18:21 ` [PATCH 5.4 12/67] of/irq: Make of_msi_map_rid() PCI " Greg Kroah-Hartman
2023-12-11 18:21 ` [PATCH 5.4 13/67] of: base: Fix some formatting issues and provide missing descriptions Greg Kroah-Hartman
2023-12-11 18:21 ` [PATCH 5.4 14/67] of: Fix kerneldoc output formatting Greg Kroah-Hartman
2023-12-11 18:21 ` [PATCH 5.4 15/67] of: Add missing Return section in kerneldoc comments Greg Kroah-Hartman
2023-12-11 18:22 ` [PATCH 5.4 16/67] of: dynamic: Fix of_reconfig_get_state_change() return value documentation Greg Kroah-Hartman
2023-12-11 18:22 ` [PATCH 5.4 17/67] ipv6: fix potential NULL deref in fib6_add() Greg Kroah-Hartman
2023-12-11 18:22 ` [PATCH 5.4 18/67] hv_netvsc: rndis_filter needs to select NLS Greg Kroah-Hartman
2023-12-11 18:22 ` Greg Kroah-Hartman [this message]
2023-12-11 18:22 ` [PATCH 5.4 20/67] net: arcnet: com20020 fix error handling Greg Kroah-Hartman
2023-12-11 18:22 ` [PATCH 5.4 21/67] arcnet: restoring support for multiple Sohard Arcnet cards Greg Kroah-Hartman
2023-12-11 18:22 ` [PATCH 5.4 22/67] ipv4: ip_gre: Avoid skb_pull() failure in ipgre_xmit() Greg Kroah-Hartman
2023-12-11 18:22 ` [PATCH 5.4 23/67] net: hns: fix fake link up on xge port Greg Kroah-Hartman
2023-12-11 18:22 ` [PATCH 5.4 24/67] netfilter: xt_owner: Fix for unsafe access of sk->sk_socket Greg Kroah-Hartman
2023-12-11 18:22 ` [PATCH 5.4 25/67] tcp: do not accept ACK of bytes we never sent Greg Kroah-Hartman
2023-12-11 18:22 ` [PATCH 5.4 26/67] bpf: sockmap, updating the sg structure should also update curr Greg Kroah-Hartman
2023-12-11 18:22 ` [PATCH 5.4 27/67] RDMA/bnxt_re: Correct module description string Greg Kroah-Hartman
2023-12-11 18:22 ` [PATCH 5.4 28/67] hwmon: (acpi_power_meter) Fix 4.29 MW bug Greg Kroah-Hartman
2023-12-11 18:22 ` [PATCH 5.4 29/67] ASoC: wm_adsp: fix memleak in wm_adsp_buffer_populate Greg Kroah-Hartman
2023-12-11 18:22 ` [PATCH 5.4 30/67] tracing: Fix a warning when allocating buffered events fails Greg Kroah-Hartman
2023-12-11 18:22 ` [PATCH 5.4 31/67] scsi: be2iscsi: Fix a memleak in beiscsi_init_wrb_handle() Greg Kroah-Hartman
2023-12-11 18:22 ` [PATCH 5.4 32/67] ARM: imx: Check return value of devm_kasprintf in imx_mmdc_perf_init Greg Kroah-Hartman
2023-12-11 18:22 ` [PATCH 5.4 33/67] ARM: dts: imx: make gpt node name generic Greg Kroah-Hartman
2023-12-11 18:22 ` [PATCH 5.4 34/67] ARM: dts: imx7: Declare timers compatible with fsl,imx6dl-gpt Greg Kroah-Hartman
2023-12-11 18:22 ` [PATCH 5.4 35/67] ALSA: pcm: fix out-of-bounds in snd_pcm_state_names Greg Kroah-Hartman
2023-12-11 18:22 ` [PATCH 5.4 36/67] nilfs2: prevent WARNING in nilfs_sufile_set_segment_usage() Greg Kroah-Hartman
2023-12-11 18:22 ` [PATCH 5.4 37/67] tracing: Always update snapshot buffer size Greg Kroah-Hartman
2023-12-11 18:22 ` [PATCH 5.4 38/67] tracing: Fix incomplete locking when disabling buffered events Greg Kroah-Hartman
2023-12-11 18:22 ` [PATCH 5.4 39/67] tracing: Fix a possible race " Greg Kroah-Hartman
2023-12-11 18:22 ` [PATCH 5.4 40/67] packet: Move reference count in packet_sock to atomic_long_t Greg Kroah-Hartman
2023-12-11 18:22 ` [PATCH 5.4 41/67] arm64: dts: mediatek: mt7622: fix memory node warning check Greg Kroah-Hartman
2023-12-11 18:22 ` [PATCH 5.4 42/67] arm64: dts: mediatek: mt8173-evb: Fix regulator-fixed node names Greg Kroah-Hartman
2023-12-11 18:22 ` [PATCH 5.4 43/67] perf/core: Add a new read format to get a number of lost samples Greg Kroah-Hartman
2023-12-11 18:22 ` [PATCH 5.4 44/67] perf: Fix perf_event_validate_size() Greg Kroah-Hartman
2023-12-11 18:22 ` [PATCH 5.4 45/67] gpiolib: sysfs: Fix error handling on failed export Greg Kroah-Hartman
2023-12-11 18:22 ` [PATCH 5.4 46/67] mmc: core: add helpers mmc_regulator_enable/disable_vqmmc Greg Kroah-Hartman
2023-12-11 18:22 ` [PATCH 5.4 47/67] mmc: sdhci-sprd: Fix vqmmc not shutting down after the card was pulled Greg Kroah-Hartman
2023-12-11 18:22 ` [PATCH 5.4 48/67] usb: gadget: f_hid: fix report descriptor allocation Greg Kroah-Hartman
2023-12-11 18:22 ` [PATCH 5.4 49/67] parport: Add support for Brainboxes IX/UC/PX parallel cards Greg Kroah-Hartman
2023-12-11 18:22 ` [PATCH 5.4 50/67] usb: typec: class: fix typec_altmode_put_partner to put plugs Greg Kroah-Hartman
2023-12-11 18:22 ` [PATCH 5.4 51/67] ARM: PL011: Fix DMA support Greg Kroah-Hartman
2023-12-11 18:22 ` [PATCH 5.4 52/67] serial: sc16is7xx: address RX timeout interrupt errata Greg Kroah-Hartman
2023-12-11 18:22 ` [PATCH 5.4 53/67] serial: 8250_omap: Add earlycon support for the AM654 UART controller Greg Kroah-Hartman
2023-12-11 18:22 ` [PATCH 5.4 54/67] x86/CPU/AMD: Check vendor in the AMD microcode callback Greg Kroah-Hartman
2023-12-11 18:22 ` [PATCH 5.4 55/67] KVM: s390/mm: Properly reset no-dat Greg Kroah-Hartman
2023-12-11 18:22 ` [PATCH 5.4 56/67] nilfs2: fix missing error check for sb_set_blocksize call Greg Kroah-Hartman
2023-12-11 18:22 ` [PATCH 5.4 57/67] io_uring/af_unix: disable sending io_uring over sockets Greg Kroah-Hartman
2023-12-11 18:22 ` [PATCH 5.4 58/67] netlink: dont call ->netlink_bind with table lock held Greg Kroah-Hartman
2023-12-11 18:22 ` [PATCH 5.4 59/67] genetlink: add CAP_NET_ADMIN test for multicast bind Greg Kroah-Hartman
2023-12-11 18:22 ` [PATCH 5.4 60/67] psample: Require CAP_NET_ADMIN when joining "packets" group Greg Kroah-Hartman
2023-12-11 18:22 ` [PATCH 5.4 61/67] drop_monitor: Require CAP_SYS_ADMIN when joining "events" group Greg Kroah-Hartman
2023-12-11 18:22 ` [PATCH 5.4 62/67] tools headers UAPI: Sync linux/perf_event.h with the kernel sources Greg Kroah-Hartman
2023-12-11 18:22 ` [PATCH 5.4 63/67] Revert "btrfs: add dmesg output for first mount and last unmount of a filesystem" Greg Kroah-Hartman
2023-12-11 18:22 ` [PATCH 5.4 64/67] cifs: Fix non-availability of dedup breaking generic/304 Greg Kroah-Hartman
2023-12-11 18:22 ` [PATCH 5.4 65/67] smb: client: fix potential NULL deref in parse_dfs_referrals() Greg Kroah-Hartman
2023-12-11 18:22 ` [PATCH 5.4 66/67] devcoredump : Serialize devcd_del work Greg Kroah-Hartman
2023-12-11 18:22 ` [PATCH 5.4 67/67] devcoredump: Send uevent once devcd is ready Greg Kroah-Hartman
2023-12-11 19:04 ` [PATCH 5.4 00/67] 5.4.264-rc1 review Florian Fainelli
2023-12-12 13:23 ` Harshit Mogalapalli
2023-12-12 16:13 ` Shuah Khan
2023-12-12 17:00 ` Guenter Roeck
2023-12-12 17:05 ` Naresh Kamboju
2023-12-12 22:19 ` Jon Hunter
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=20231211182015.914777215@linuxfoundation.org \
--to=gregkh@linuxfoundation.org \
--cc=a.darwish@linutronix.de \
--cc=bigeasy@linutronix.de \
--cc=kuba@kernel.org \
--cc=patches@lists.linux.dev \
--cc=sashal@kernel.org \
--cc=stable@vger.kernel.org \
/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