Commit ef0a59924a795ccb4ced0ae1722a337745a1b045
Merge tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
Pull SCSI fixes from James Bottomley: "This is a set of two small fixes, both to code which went in during the merge window: cxgb4i has a scheduling in atomic bug in its new ipv6 code and uas fails to work properly with the new scsi-mq code" * tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: [SCSI] uas: disable use of blk-mq I/O path [SCSI] cxgb4i: avoid holding mutex in interrupt context
Showing 4 changed files Side-by-side Diff
drivers/scsi/cxgbi/cxgb4i/cxgb4i.c
... | ... | @@ -1647,7 +1647,7 @@ |
1647 | 1647 | if (event_dev->priv_flags & IFF_802_1Q_VLAN) |
1648 | 1648 | event_dev = vlan_dev_real_dev(event_dev); |
1649 | 1649 | |
1650 | - cdev = cxgbi_device_find_by_netdev(event_dev, NULL); | |
1650 | + cdev = cxgbi_device_find_by_netdev_rcu(event_dev, NULL); | |
1651 | 1651 | |
1652 | 1652 | if (!cdev) |
1653 | 1653 | return ret; |
drivers/scsi/cxgbi/libcxgbi.c
... | ... | @@ -57,6 +57,9 @@ |
57 | 57 | static LIST_HEAD(cdev_list); |
58 | 58 | static DEFINE_MUTEX(cdev_mutex); |
59 | 59 | |
60 | +static LIST_HEAD(cdev_rcu_list); | |
61 | +static DEFINE_SPINLOCK(cdev_rcu_lock); | |
62 | + | |
60 | 63 | int cxgbi_device_portmap_create(struct cxgbi_device *cdev, unsigned int base, |
61 | 64 | unsigned int max_conn) |
62 | 65 | { |
... | ... | @@ -142,6 +145,10 @@ |
142 | 145 | list_add_tail(&cdev->list_head, &cdev_list); |
143 | 146 | mutex_unlock(&cdev_mutex); |
144 | 147 | |
148 | + spin_lock(&cdev_rcu_lock); | |
149 | + list_add_tail_rcu(&cdev->rcu_node, &cdev_rcu_list); | |
150 | + spin_unlock(&cdev_rcu_lock); | |
151 | + | |
145 | 152 | log_debug(1 << CXGBI_DBG_DEV, |
146 | 153 | "cdev 0x%p, p# %u.\n", cdev, nports); |
147 | 154 | return cdev; |
148 | 155 | |
... | ... | @@ -153,9 +160,16 @@ |
153 | 160 | log_debug(1 << CXGBI_DBG_DEV, |
154 | 161 | "cdev 0x%p, p# %u,%s.\n", |
155 | 162 | cdev, cdev->nports, cdev->nports ? cdev->ports[0]->name : ""); |
163 | + | |
156 | 164 | mutex_lock(&cdev_mutex); |
157 | 165 | list_del(&cdev->list_head); |
158 | 166 | mutex_unlock(&cdev_mutex); |
167 | + | |
168 | + spin_lock(&cdev_rcu_lock); | |
169 | + list_del_rcu(&cdev->rcu_node); | |
170 | + spin_unlock(&cdev_rcu_lock); | |
171 | + synchronize_rcu(); | |
172 | + | |
159 | 173 | cxgbi_device_destroy(cdev); |
160 | 174 | } |
161 | 175 | EXPORT_SYMBOL_GPL(cxgbi_device_unregister); |
... | ... | @@ -167,12 +181,9 @@ |
167 | 181 | mutex_lock(&cdev_mutex); |
168 | 182 | list_for_each_entry_safe(cdev, tmp, &cdev_list, list_head) { |
169 | 183 | if ((cdev->flags & flag) == flag) { |
170 | - log_debug(1 << CXGBI_DBG_DEV, | |
171 | - "cdev 0x%p, p# %u,%s.\n", | |
172 | - cdev, cdev->nports, cdev->nports ? | |
173 | - cdev->ports[0]->name : ""); | |
174 | - list_del(&cdev->list_head); | |
175 | - cxgbi_device_destroy(cdev); | |
184 | + mutex_unlock(&cdev_mutex); | |
185 | + cxgbi_device_unregister(cdev); | |
186 | + mutex_lock(&cdev_mutex); | |
176 | 187 | } |
177 | 188 | } |
178 | 189 | mutex_unlock(&cdev_mutex); |
... | ... | @@ -191,6 +202,7 @@ |
191 | 202 | } |
192 | 203 | } |
193 | 204 | mutex_unlock(&cdev_mutex); |
205 | + | |
194 | 206 | log_debug(1 << CXGBI_DBG_DEV, |
195 | 207 | "lldev 0x%p, NO match found.\n", lldev); |
196 | 208 | return NULL; |
... | ... | @@ -229,6 +241,39 @@ |
229 | 241 | return NULL; |
230 | 242 | } |
231 | 243 | EXPORT_SYMBOL_GPL(cxgbi_device_find_by_netdev); |
244 | + | |
245 | +struct cxgbi_device *cxgbi_device_find_by_netdev_rcu(struct net_device *ndev, | |
246 | + int *port) | |
247 | +{ | |
248 | + struct net_device *vdev = NULL; | |
249 | + struct cxgbi_device *cdev; | |
250 | + int i; | |
251 | + | |
252 | + if (ndev->priv_flags & IFF_802_1Q_VLAN) { | |
253 | + vdev = ndev; | |
254 | + ndev = vlan_dev_real_dev(ndev); | |
255 | + pr_info("vlan dev %s -> %s.\n", vdev->name, ndev->name); | |
256 | + } | |
257 | + | |
258 | + rcu_read_lock(); | |
259 | + list_for_each_entry_rcu(cdev, &cdev_rcu_list, rcu_node) { | |
260 | + for (i = 0; i < cdev->nports; i++) { | |
261 | + if (ndev == cdev->ports[i]) { | |
262 | + cdev->hbas[i]->vdev = vdev; | |
263 | + rcu_read_unlock(); | |
264 | + if (port) | |
265 | + *port = i; | |
266 | + return cdev; | |
267 | + } | |
268 | + } | |
269 | + } | |
270 | + rcu_read_unlock(); | |
271 | + | |
272 | + log_debug(1 << CXGBI_DBG_DEV, | |
273 | + "ndev 0x%p, %s, NO match found.\n", ndev, ndev->name); | |
274 | + return NULL; | |
275 | +} | |
276 | +EXPORT_SYMBOL_GPL(cxgbi_device_find_by_netdev_rcu); | |
232 | 277 | |
233 | 278 | static struct cxgbi_device *cxgbi_device_find_by_mac(struct net_device *ndev, |
234 | 279 | int *port) |
drivers/scsi/cxgbi/libcxgbi.h
... | ... | @@ -527,6 +527,7 @@ |
527 | 527 | #define CXGBI_FLAG_IPV4_SET 0x10 |
528 | 528 | struct cxgbi_device { |
529 | 529 | struct list_head list_head; |
530 | + struct list_head rcu_node; | |
530 | 531 | unsigned int flags; |
531 | 532 | struct net_device **ports; |
532 | 533 | void *lldev; |
... | ... | @@ -709,6 +710,8 @@ |
709 | 710 | void cxgbi_device_unregister_all(unsigned int flag); |
710 | 711 | struct cxgbi_device *cxgbi_device_find_by_lldev(void *); |
711 | 712 | struct cxgbi_device *cxgbi_device_find_by_netdev(struct net_device *, int *); |
713 | +struct cxgbi_device *cxgbi_device_find_by_netdev_rcu(struct net_device *, | |
714 | + int *); | |
712 | 715 | int cxgbi_hbas_add(struct cxgbi_device *, u64, unsigned int, |
713 | 716 | struct scsi_host_template *, |
714 | 717 | struct scsi_transport_template *); |
drivers/usb/storage/uas.c
... | ... | @@ -970,6 +970,13 @@ |
970 | 970 | .cmd_per_lun = 1, /* until we override it */ |
971 | 971 | .skip_settle_delay = 1, |
972 | 972 | .ordered_tag = 1, |
973 | + | |
974 | + /* | |
975 | + * The uas drivers expects tags not to be bigger than the maximum | |
976 | + * per-device queue depth, which is not true with the blk-mq tag | |
977 | + * allocator. | |
978 | + */ | |
979 | + .disable_blk_mq = true, | |
973 | 980 | }; |
974 | 981 | |
975 | 982 | #define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ |