Commit 932f19de6af9f45784d7fb730dea50525b3b5aac
Committed by
David S. Miller
1 parent
db84bf43ef
Exists in
ti-lsk-linux-4.1.y
and in
10 other branches
tg3: Release tp->lock before invoking synchronize_irq()
synchronize_irq() can sleep waiting, for pending IRQ handlers so driver should release the tp->lock spin lock before invoking synchronize_irq() Reported-by: Peter Hurley <peter@hurleysoftware.com> Tested-by: Peter Hurley <peter@hurleysoftware.com> Signed-off-by: Prashant Sreedharan <prashant@broadcom.com> Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Showing 1 changed file with 12 additions and 0 deletions Side-by-side Diff
drivers/net/ethernet/broadcom/tg3.c
... | ... | @@ -7413,6 +7413,8 @@ |
7413 | 7413 | } |
7414 | 7414 | |
7415 | 7415 | static void tg3_irq_quiesce(struct tg3 *tp) |
7416 | + __releases(tp->lock) | |
7417 | + __acquires(tp->lock) | |
7416 | 7418 | { |
7417 | 7419 | int i; |
7418 | 7420 | |
7419 | 7421 | |
... | ... | @@ -7421,8 +7423,12 @@ |
7421 | 7423 | tp->irq_sync = 1; |
7422 | 7424 | smp_mb(); |
7423 | 7425 | |
7426 | + spin_unlock_bh(&tp->lock); | |
7427 | + | |
7424 | 7428 | for (i = 0; i < tp->irq_cnt; i++) |
7425 | 7429 | synchronize_irq(tp->napi[i].irq_vec); |
7430 | + | |
7431 | + spin_lock_bh(&tp->lock); | |
7426 | 7432 | } |
7427 | 7433 | |
7428 | 7434 | /* Fully shutdown all tg3 driver activity elsewhere in the system. |
... | ... | @@ -9018,6 +9024,8 @@ |
9018 | 9024 | |
9019 | 9025 | /* tp->lock is held. */ |
9020 | 9026 | static int tg3_chip_reset(struct tg3 *tp) |
9027 | + __releases(tp->lock) | |
9028 | + __acquires(tp->lock) | |
9021 | 9029 | { |
9022 | 9030 | u32 val; |
9023 | 9031 | void (*write_op)(struct tg3 *, u32, u32); |
9024 | 9032 | |
... | ... | @@ -9073,8 +9081,12 @@ |
9073 | 9081 | } |
9074 | 9082 | smp_mb(); |
9075 | 9083 | |
9084 | + tg3_full_unlock(tp); | |
9085 | + | |
9076 | 9086 | for (i = 0; i < tp->irq_cnt; i++) |
9077 | 9087 | synchronize_irq(tp->napi[i].irq_vec); |
9088 | + | |
9089 | + tg3_full_lock(tp, 0); | |
9078 | 9090 | |
9079 | 9091 | if (tg3_asic_rev(tp) == ASIC_REV_57780) { |
9080 | 9092 | val = tr32(TG3_PCIE_LNKCTL) & ~TG3_PCIE_LNKCTL_L1_PLL_PD_EN; |
-
mentioned in commit d0af71
-
mentioned in commit d0af71
-
mentioned in commit d0af71
-
mentioned in commit d0af71
-
mentioned in commit d0af71
-
mentioned in commit d0af71
-
mentioned in commit d0af71
-
mentioned in commit d0af71
-
mentioned in commit d0af71
-
mentioned in commit d0af71
-
mentioned in commit d0af71
-
mentioned in commit d0af71
-
mentioned in commit d0af71