]>
Commit | Line | Data |
---|---|---|
eefdbb8e GKH |
1 | From 24e94454c8cb6a13634f5a2f5a01da53a546a58d Mon Sep 17 00:00:00 2001 |
2 | From: Max Filippov <jcmvbkbc@gmail.com> | |
3 | Date: Fri, 3 Apr 2015 09:56:21 +0300 | |
4 | Subject: xtensa: ISS: fix locking in TAP network adapter | |
5 | ||
6 | From: Max Filippov <jcmvbkbc@gmail.com> | |
7 | ||
8 | commit 24e94454c8cb6a13634f5a2f5a01da53a546a58d upstream. | |
9 | ||
10 | - don't lock lp->lock in the iss_net_timer for the call of iss_net_poll, | |
11 | it will lock it itself; | |
12 | - invert order of lp->lock and opened_lock acquisition in the | |
13 | iss_net_open to make it consistent with iss_net_poll; | |
14 | - replace spin_lock with spin_lock_bh when acquiring locks used in | |
15 | iss_net_timer from non-atomic context; | |
16 | - replace spin_lock_irqsave with spin_lock_bh in the iss_net_start_xmit | |
17 | as the driver doesn't use lp->lock in the hard IRQ context; | |
18 | - replace __SPIN_LOCK_UNLOCKED(lp.lock) with spin_lock_init, otherwise | |
19 | lockdep is unhappy about using non-static key. | |
20 | ||
21 | Signed-off-by: Max Filippov <jcmvbkbc@gmail.com> | |
22 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
23 | ||
24 | --- | |
25 | arch/xtensa/platforms/iss/network.c | 29 +++++++++++++++-------------- | |
26 | 1 file changed, 15 insertions(+), 14 deletions(-) | |
27 | ||
28 | --- a/arch/xtensa/platforms/iss/network.c | |
29 | +++ b/arch/xtensa/platforms/iss/network.c | |
30 | @@ -349,8 +349,8 @@ static void iss_net_timer(unsigned long | |
31 | { | |
32 | struct iss_net_private *lp = (struct iss_net_private *)priv; | |
33 | ||
34 | - spin_lock(&lp->lock); | |
35 | iss_net_poll(); | |
36 | + spin_lock(&lp->lock); | |
37 | mod_timer(&lp->timer, jiffies + lp->timer_val); | |
38 | spin_unlock(&lp->lock); | |
39 | } | |
40 | @@ -361,7 +361,7 @@ static int iss_net_open(struct net_devic | |
41 | struct iss_net_private *lp = netdev_priv(dev); | |
42 | int err; | |
43 | ||
44 | - spin_lock(&lp->lock); | |
45 | + spin_lock_bh(&lp->lock); | |
46 | ||
47 | err = lp->tp.open(lp); | |
48 | if (err < 0) | |
49 | @@ -376,9 +376,11 @@ static int iss_net_open(struct net_devic | |
50 | while ((err = iss_net_rx(dev)) > 0) | |
51 | ; | |
52 | ||
53 | - spin_lock(&opened_lock); | |
54 | + spin_unlock_bh(&lp->lock); | |
55 | + spin_lock_bh(&opened_lock); | |
56 | list_add(&lp->opened_list, &opened); | |
57 | - spin_unlock(&opened_lock); | |
58 | + spin_unlock_bh(&opened_lock); | |
59 | + spin_lock_bh(&lp->lock); | |
60 | ||
61 | init_timer(&lp->timer); | |
62 | lp->timer_val = ISS_NET_TIMER_VALUE; | |
63 | @@ -387,7 +389,7 @@ static int iss_net_open(struct net_devic | |
64 | mod_timer(&lp->timer, jiffies + lp->timer_val); | |
65 | ||
66 | out: | |
67 | - spin_unlock(&lp->lock); | |
68 | + spin_unlock_bh(&lp->lock); | |
69 | return err; | |
70 | } | |
71 | ||
72 | @@ -395,7 +397,7 @@ static int iss_net_close(struct net_devi | |
73 | { | |
74 | struct iss_net_private *lp = netdev_priv(dev); | |
75 | netif_stop_queue(dev); | |
76 | - spin_lock(&lp->lock); | |
77 | + spin_lock_bh(&lp->lock); | |
78 | ||
79 | spin_lock(&opened_lock); | |
80 | list_del(&opened); | |
81 | @@ -405,18 +407,17 @@ static int iss_net_close(struct net_devi | |
82 | ||
83 | lp->tp.close(lp); | |
84 | ||
85 | - spin_unlock(&lp->lock); | |
86 | + spin_unlock_bh(&lp->lock); | |
87 | return 0; | |
88 | } | |
89 | ||
90 | static int iss_net_start_xmit(struct sk_buff *skb, struct net_device *dev) | |
91 | { | |
92 | struct iss_net_private *lp = netdev_priv(dev); | |
93 | - unsigned long flags; | |
94 | int len; | |
95 | ||
96 | netif_stop_queue(dev); | |
97 | - spin_lock_irqsave(&lp->lock, flags); | |
98 | + spin_lock_bh(&lp->lock); | |
99 | ||
100 | len = lp->tp.write(lp, &skb); | |
101 | ||
102 | @@ -438,7 +439,7 @@ static int iss_net_start_xmit(struct sk_ | |
103 | pr_err("%s: %s failed(%d)\n", dev->name, __func__, len); | |
104 | } | |
105 | ||
106 | - spin_unlock_irqrestore(&lp->lock, flags); | |
107 | + spin_unlock_bh(&lp->lock); | |
108 | ||
109 | dev_kfree_skb(skb); | |
110 | return NETDEV_TX_OK; | |
111 | @@ -466,9 +467,9 @@ static int iss_net_set_mac(struct net_de | |
112 | ||
113 | if (!is_valid_ether_addr(hwaddr->sa_data)) | |
114 | return -EADDRNOTAVAIL; | |
115 | - spin_lock(&lp->lock); | |
116 | + spin_lock_bh(&lp->lock); | |
117 | memcpy(dev->dev_addr, hwaddr->sa_data, ETH_ALEN); | |
118 | - spin_unlock(&lp->lock); | |
119 | + spin_unlock_bh(&lp->lock); | |
120 | return 0; | |
121 | } | |
122 | ||
123 | @@ -520,11 +521,11 @@ static int iss_net_configure(int index, | |
124 | *lp = (struct iss_net_private) { | |
125 | .device_list = LIST_HEAD_INIT(lp->device_list), | |
126 | .opened_list = LIST_HEAD_INIT(lp->opened_list), | |
127 | - .lock = __SPIN_LOCK_UNLOCKED(lp.lock), | |
128 | .dev = dev, | |
129 | .index = index, | |
130 | - }; | |
131 | + }; | |
132 | ||
133 | + spin_lock_init(&lp->lock); | |
134 | /* | |
135 | * If this name ends up conflicting with an existing registered | |
136 | * netdevice, that is OK, register_netdev{,ice}() will notice this |