From c36a68fab1c3ddf71918cd1e5937a647cd80ba2b Mon Sep 17 00:00:00 2001 From: Anna-Maria Gleixner Date: Fri, 4 May 2018 17:17:46 +0200 Subject: [PATCH 1/4] net: u64_stats_sync: Remove functions without user Commit 67db3e4bfbc9 ("tcp: no longer hold ehash lock while calling tcp_get_info()") removes the only users of u64_stats_update_end/begin_raw() without removing the function in header file. Remove no longer used functions. Cc: Eric Dumazet Signed-off-by: Anna-Maria Gleixner Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: David S. Miller --- include/linux/u64_stats_sync.h | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/include/linux/u64_stats_sync.h b/include/linux/u64_stats_sync.h index 07ee0f84a46c..a27604f99ed0 100644 --- a/include/linux/u64_stats_sync.h +++ b/include/linux/u64_stats_sync.h @@ -112,20 +112,6 @@ u64_stats_update_end_irqrestore(struct u64_stats_sync *syncp, #endif } -static inline void u64_stats_update_begin_raw(struct u64_stats_sync *syncp) -{ -#if BITS_PER_LONG==32 && defined(CONFIG_SMP) - raw_write_seqcount_begin(&syncp->seq); -#endif -} - -static inline void u64_stats_update_end_raw(struct u64_stats_sync *syncp) -{ -#if BITS_PER_LONG==32 && defined(CONFIG_SMP) - raw_write_seqcount_end(&syncp->seq); -#endif -} - static inline unsigned int __u64_stats_fetch_begin(const struct u64_stats_sync *syncp) { #if BITS_PER_LONG==32 && defined(CONFIG_SMP) From 577b995be5f5235e7bfe48536c72a5d1f0084f6b Mon Sep 17 00:00:00 2001 From: Anna-Maria Gleixner Date: Fri, 4 May 2018 17:17:47 +0200 Subject: [PATCH 2/4] net: 3com: 3c59x: Move boomerang/vortex conditional into function If vp->full_bus_master_tx is set, vp->full_bus_master_rx is set as well (see vortex_probe1()). Therefore the conditionals for the decision if boomerang or vortex ISR is executed have the same result. Instead of repeating the explicit conditional execution of the boomerang/vortex ISR, move it into an own function. No functional change. Cc: Steffen Klassert Signed-off-by: Anna-Maria Gleixner Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: David S. Miller --- drivers/net/ethernet/3com/3c59x.c | 34 ++++++++++++++++++------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/drivers/net/ethernet/3com/3c59x.c b/drivers/net/ethernet/3com/3c59x.c index 36c8950dbd2d..0cfdb07f3e59 100644 --- a/drivers/net/ethernet/3com/3c59x.c +++ b/drivers/net/ethernet/3com/3c59x.c @@ -765,8 +765,9 @@ static netdev_tx_t boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev); static int vortex_rx(struct net_device *dev); static int boomerang_rx(struct net_device *dev); -static irqreturn_t vortex_interrupt(int irq, void *dev_id); -static irqreturn_t boomerang_interrupt(int irq, void *dev_id); +static irqreturn_t vortex_boomerang_interrupt(int irq, void *dev_id); +static irqreturn_t _vortex_interrupt(int irq, struct net_device *dev); +static irqreturn_t _boomerang_interrupt(int irq, struct net_device *dev); static int vortex_close(struct net_device *dev); static void dump_tx_ring(struct net_device *dev); static void update_stats(void __iomem *ioaddr, struct net_device *dev); @@ -838,10 +839,9 @@ MODULE_PARM_DESC(use_mmio, "3c59x: use memory-mapped PCI I/O resource (0-1)"); #ifdef CONFIG_NET_POLL_CONTROLLER static void poll_vortex(struct net_device *dev) { - struct vortex_private *vp = netdev_priv(dev); unsigned long flags; local_irq_save(flags); - (vp->full_bus_master_rx ? boomerang_interrupt:vortex_interrupt)(dev->irq,dev); + vortex_boomerang_interrupt(dev->irq, dev); local_irq_restore(flags); } #endif @@ -1729,8 +1729,7 @@ vortex_open(struct net_device *dev) dma_addr_t dma; /* Use the now-standard shared IRQ implementation. */ - if ((retval = request_irq(dev->irq, vp->full_bus_master_rx ? - boomerang_interrupt : vortex_interrupt, IRQF_SHARED, dev->name, dev))) { + if ((retval = request_irq(dev->irq, vortex_boomerang_interrupt, IRQF_SHARED, dev->name, dev))) { pr_err("%s: Could not reserve IRQ %d\n", dev->name, dev->irq); goto err; } @@ -1911,10 +1910,7 @@ static void vortex_tx_timeout(struct net_device *dev) */ unsigned long flags; local_irq_save(flags); - if (vp->full_bus_master_tx) - boomerang_interrupt(dev->irq, dev); - else - vortex_interrupt(dev->irq, dev); + vortex_boomerang_interrupt(dev->irq, dev); local_irq_restore(flags); } } @@ -2267,9 +2263,8 @@ out_dma_err: */ static irqreturn_t -vortex_interrupt(int irq, void *dev_id) +_vortex_interrupt(int irq, struct net_device *dev) { - struct net_device *dev = dev_id; struct vortex_private *vp = netdev_priv(dev); void __iomem *ioaddr; int status; @@ -2386,9 +2381,8 @@ handler_exit: */ static irqreturn_t -boomerang_interrupt(int irq, void *dev_id) +_boomerang_interrupt(int irq, struct net_device *dev) { - struct net_device *dev = dev_id; struct vortex_private *vp = netdev_priv(dev); void __iomem *ioaddr; int status; @@ -2526,6 +2520,18 @@ handler_exit: return IRQ_RETVAL(handled); } +static irqreturn_t +vortex_boomerang_interrupt(int irq, void *dev_id) +{ + struct net_device *dev = dev_id; + struct vortex_private *vp = netdev_priv(dev); + + if (vp->full_bus_master_rx) + return _boomerang_interrupt(dev->irq, dev); + else + return _vortex_interrupt(dev->irq, dev); +} + static int vortex_rx(struct net_device *dev) { struct vortex_private *vp = netdev_priv(dev); From 47f66c766c8d91fe0a20b85359ce13e467863697 Mon Sep 17 00:00:00 2001 From: Anna-Maria Gleixner Date: Fri, 4 May 2018 17:17:48 +0200 Subject: [PATCH 3/4] net: 3com: 3c59x: Pull locking out of ISR Locking is done in the same way in _vortex_interrupt() and _boomerang_interrupt(). To prevent duplication, move the locking into the calling vortex_boomerang_interrupt() function. No functional change. Cc: Steffen Klassert Signed-off-by: Anna-Maria Gleixner Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: David S. Miller --- drivers/net/ethernet/3com/3c59x.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/drivers/net/ethernet/3com/3c59x.c b/drivers/net/ethernet/3com/3c59x.c index 0cfdb07f3e59..fdafe25da153 100644 --- a/drivers/net/ethernet/3com/3c59x.c +++ b/drivers/net/ethernet/3com/3c59x.c @@ -2273,7 +2273,6 @@ _vortex_interrupt(int irq, struct net_device *dev) unsigned int bytes_compl = 0, pkts_compl = 0; ioaddr = vp->ioaddr; - spin_lock(&vp->lock); status = ioread16(ioaddr + EL3_STATUS); @@ -2371,7 +2370,6 @@ _vortex_interrupt(int irq, struct net_device *dev) pr_debug("%s: exiting interrupt, status %4.4x.\n", dev->name, status); handler_exit: - spin_unlock(&vp->lock); return IRQ_RETVAL(handled); } @@ -2392,12 +2390,6 @@ _boomerang_interrupt(int irq, struct net_device *dev) ioaddr = vp->ioaddr; - - /* - * It seems dopey to put the spinlock this early, but we could race against vortex_tx_timeout - * and boomerang_start_xmit - */ - spin_lock(&vp->lock); vp->handling_irq = 1; status = ioread16(ioaddr + EL3_STATUS); @@ -2516,7 +2508,6 @@ _boomerang_interrupt(int irq, struct net_device *dev) dev->name, status); handler_exit: vp->handling_irq = 0; - spin_unlock(&vp->lock); return IRQ_RETVAL(handled); } @@ -2525,11 +2516,18 @@ vortex_boomerang_interrupt(int irq, void *dev_id) { struct net_device *dev = dev_id; struct vortex_private *vp = netdev_priv(dev); + irqreturn_t ret; + + spin_lock(&vp->lock); if (vp->full_bus_master_rx) - return _boomerang_interrupt(dev->irq, dev); + ret = _boomerang_interrupt(dev->irq, dev); else - return _vortex_interrupt(dev->irq, dev); + ret = _vortex_interrupt(dev->irq, dev); + + spin_unlock(&vp->lock); + + return ret; } static int vortex_rx(struct net_device *dev) From dea4c96e65b3c5520f1e9d9e038e79d59f5688f1 Mon Sep 17 00:00:00 2001 From: Anna-Maria Gleixner Date: Fri, 4 May 2018 17:17:49 +0200 Subject: [PATCH 4/4] net: 3com: 3c59x: irq save variant of ISR When vortex_boomerang_interrupt() is invoked from vortex_tx_timeout() or poll_vortex() interrupts must be disabled. This detaches the interrupt disable logic from locking which requires patching for PREEMPT_RT. The advantage of avoiding spin_lock_irqsave() in the interrupt handler is minimal, but converting it removes all the extra code for callers which come not from interrupt context. Cc: Steffen Klassert Signed-off-by: Anna-Maria Gleixner Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: David S. Miller --- drivers/net/ethernet/3com/3c59x.c | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/drivers/net/ethernet/3com/3c59x.c b/drivers/net/ethernet/3com/3c59x.c index fdafe25da153..cabbe227bb98 100644 --- a/drivers/net/ethernet/3com/3c59x.c +++ b/drivers/net/ethernet/3com/3c59x.c @@ -839,10 +839,7 @@ MODULE_PARM_DESC(use_mmio, "3c59x: use memory-mapped PCI I/O resource (0-1)"); #ifdef CONFIG_NET_POLL_CONTROLLER static void poll_vortex(struct net_device *dev) { - unsigned long flags; - local_irq_save(flags); vortex_boomerang_interrupt(dev->irq, dev); - local_irq_restore(flags); } #endif @@ -1904,15 +1901,7 @@ static void vortex_tx_timeout(struct net_device *dev) pr_err("%s: Interrupt posted but not delivered --" " IRQ blocked by another device?\n", dev->name); /* Bad idea here.. but we might as well handle a few events. */ - { - /* - * Block interrupts because vortex_interrupt does a bare spin_lock() - */ - unsigned long flags; - local_irq_save(flags); - vortex_boomerang_interrupt(dev->irq, dev); - local_irq_restore(flags); - } + vortex_boomerang_interrupt(dev->irq, dev); } if (vortex_debug > 0) @@ -2516,16 +2505,17 @@ vortex_boomerang_interrupt(int irq, void *dev_id) { struct net_device *dev = dev_id; struct vortex_private *vp = netdev_priv(dev); + unsigned long flags; irqreturn_t ret; - spin_lock(&vp->lock); + spin_lock_irqsave(&vp->lock, flags); if (vp->full_bus_master_rx) ret = _boomerang_interrupt(dev->irq, dev); else ret = _vortex_interrupt(dev->irq, dev); - spin_unlock(&vp->lock); + spin_unlock_irqrestore(&vp->lock, flags); return ret; }