]> rtime.felk.cvut.cz Git - zynq/linux.git/commitdiff
arm64: zynqmp: macb: release spinlock before calling ptp_clock_unregister
authorYasir-Khan <yasir_khan@mentor.com>
Thu, 1 Dec 2016 23:19:52 +0000 (04:19 +0500)
committerMichal Simek <michal.simek@xilinx.com>
Tue, 20 Dec 2016 06:58:08 +0000 (07:58 +0100)
macb_ptp_close calls ptp_clock_unregister with spinlock locked which
further calls device_destroy which might block on mutex required for
deleting the device node and sleep. This sleeping while holding the
spinlock triggers the below kernel panic.

[  130.911589] BUG: scheduling while atomic: connmand/424/0x00000002
[  130.917596] Modules linked in: mali(O) nfsd
[  130.921766] CPU: 1 PID: 424 Comm: connmand Tainted: G  O
[  130.929486] Hardware name: ZynqMP ZCU102 RevB (DT)
[  130.934275] Call trace:
[  130.936702] [<ffffffc0000889e8>] dump_backtrace+0x0/0x158
[  130.942085] [<ffffffc000088b64>] show_stack+0x24/0x30
[  130.947110] [<ffffffc00031af3c>] dump_stack+0x94/0xd0
[  130.952329] [<ffffffc0000bee2c>] __schedule_bug+0x5c/0x70
[  130.968469] [<ffffffc000673cb4>] schedule+0x4c/0xc0
[  130.975675] [<ffffffc000676d04>] schedule_timeout+0x1cc/0x260
[  130.981408] [<ffffffc000674950>] wait_for_common+0xa8/0x150
[  130.987124] [<ffffffc000674a20>] wait_for_completion+0x28/0x38
[  130.993213] [<ffffffc0003f6d38>] devtmpfs_delete_node+0xa8/0xe8
[  130.999104] [<ffffffc0003ea278>] device_del+0x198/0x210
[  131.007822] [<ffffffc0003ea3cc>] device_destroy+0x54/0x68
[  131.013178] [<ffffffc0004fbb74>] ptp_clock_unregister+0x5c/0x78
[  131.019242] [<ffffffc00048b780>] macb_close+0xf8/0x100
[  131.024645] [<ffffffc000565c04>] __dev_close_many+0x8c/0xd8
[  131.030190] [<ffffffc000565d80>] __dev_close+0x30/0x48
[  131.035299] [<ffffffc00056eb48>] __dev_change_flags+0xa0/0x150
[  131.041132] [<ffffffc00056ec2c>] dev_change_flags+0x34/0x70
[  131.046671] [<ffffffc0005d3cbc>] devinet_ioctl+0x67c/0x718
[  131.052151] [<ffffffc0005d56e4>] inet_ioctl+0xec/0x128
[  131.057259] [<ffffffc00054ceec>] sock_ioctl+0x174/0x308
[  131.062480] [<ffffffc0001c33ac>] do_vfs_ioctl+0x354/0x5f8
[  131.067847] [<ffffffc0001c36a0>] SyS_ioctl+0x50/0x88
[  131.072808] [<ffffffc0000851f0>] el0_svc_naked+0x24/0x28
[  131.079364] ------------[ cut here ]------------

Therefore release the spinlock before performing ptp device cleanup.

Signed-off-by: Yasir-Khan <yasir_khan@mentor.com>
Acked-by: Harini Katakam <harinik@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
drivers/net/ethernet/cadence/macb.c

index c95357fd7c60fd2af743a61c4a0bdfba393efc54..bc31bbd9d1e9f7a09d43edb432ce03b02ad9420d 100644 (file)
@@ -1863,11 +1863,15 @@ static int macb_ptp_enable(struct ptp_clock_info *ptp,
 
 static void macb_ptp_close(struct macb *bp)
 {
+       unsigned long flags;
+
+       spin_lock_irqsave(&bp->lock, flags);
        /* Clear the time counters */
        gem_writel(bp, 1588NS, 0);
        gem_writel(bp, 1588S, 0);
        gem_writel(bp, 1588ADJ, 0);
        gem_writel(bp, 1588INCR, 0);
+       spin_unlock_irqrestore(&bp->lock, flags);
 
        ptp_clock_unregister(bp->ptp_clock);
 }
@@ -2335,11 +2339,12 @@ static int macb_close(struct net_device *dev)
 
        spin_lock_irqsave(&bp->lock, flags);
        macb_reset_hw(bp);
+       netif_carrier_off(dev);
+       spin_unlock_irqrestore(&bp->lock, flags);
+
        if ((gem_readl(bp, DCFG5) & GEM_BIT(TSU)) &&
            (bp->caps & MACB_CAPS_TSU))
                macb_ptp_close(bp);
-       netif_carrier_off(dev);
-       spin_unlock_irqrestore(&bp->lock, flags);
 
        macb_free_consistent(bp);