diff options
author | Ahmed S. Darwish <a.darwish@linutronix.de> | 2021-01-28 20:48:02 +0100 |
---|---|---|
committer | Jakub Kicinski <kuba@kernel.org> | 2021-01-30 05:54:06 +0100 |
commit | 01365633bd1c836240f9bbf86bbeee749795480a (patch) | |
tree | 3577317374618d0bc6a75a91ff346ba916e3868e /drivers/net/arcnet/arc-rimi.c | |
parent | Merge https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf (diff) | |
download | linux-01365633bd1c836240f9bbf86bbeee749795480a.tar.xz linux-01365633bd1c836240f9bbf86bbeee749795480a.zip |
net: arcnet: Fix RESET flag handling
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>
Diffstat (limited to 'drivers/net/arcnet/arc-rimi.c')
-rw-r--r-- | drivers/net/arcnet/arc-rimi.c | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/drivers/net/arcnet/arc-rimi.c b/drivers/net/arcnet/arc-rimi.c index 98df38fe553c..12d085405bd0 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 |