diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-10-05 13:16:11 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-10-05 13:16:11 -0400 |
| commit | ef0a59924a795ccb4ced0ae1722a337745a1b045 (patch) | |
| tree | dddd5b2cccf2fe0d8ec27c68659e027d3e9a4064 /drivers | |
| parent | 7b6ea43d3f90ba1db87883126c2c09777f51d3d6 (diff) | |
| parent | 2c2d831c81ec75a7b0d8e28caa8e3d9c1fe546f9 (diff) | |
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
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/scsi/cxgbi/cxgb4i/cxgb4i.c | 2 | ||||
| -rw-r--r-- | drivers/scsi/cxgbi/libcxgbi.c | 57 | ||||
| -rw-r--r-- | drivers/scsi/cxgbi/libcxgbi.h | 3 | ||||
| -rw-r--r-- | drivers/usb/storage/uas.c | 7 |
4 files changed, 62 insertions, 7 deletions
diff --git a/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c index 79788a12712d..02e69e7ee4a3 100644 --- a/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c +++ b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c | |||
| @@ -1647,7 +1647,7 @@ static int cxgbi_inet6addr_handler(struct notifier_block *this, | |||
| 1647 | if (event_dev->priv_flags & IFF_802_1Q_VLAN) | 1647 | if (event_dev->priv_flags & IFF_802_1Q_VLAN) |
| 1648 | event_dev = vlan_dev_real_dev(event_dev); | 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 | if (!cdev) | 1652 | if (!cdev) |
| 1653 | return ret; | 1653 | return ret; |
diff --git a/drivers/scsi/cxgbi/libcxgbi.c b/drivers/scsi/cxgbi/libcxgbi.c index d65df6dc106f..addd1dddce14 100644 --- a/drivers/scsi/cxgbi/libcxgbi.c +++ b/drivers/scsi/cxgbi/libcxgbi.c | |||
| @@ -57,6 +57,9 @@ MODULE_PARM_DESC(dbg_level, "libiscsi debug level (default=0)"); | |||
| 57 | static LIST_HEAD(cdev_list); | 57 | static LIST_HEAD(cdev_list); |
| 58 | static DEFINE_MUTEX(cdev_mutex); | 58 | static DEFINE_MUTEX(cdev_mutex); |
| 59 | 59 | ||
| 60 | static LIST_HEAD(cdev_rcu_list); | ||
| 61 | static DEFINE_SPINLOCK(cdev_rcu_lock); | ||
| 62 | |||
| 60 | int cxgbi_device_portmap_create(struct cxgbi_device *cdev, unsigned int base, | 63 | int cxgbi_device_portmap_create(struct cxgbi_device *cdev, unsigned int base, |
| 61 | unsigned int max_conn) | 64 | unsigned int max_conn) |
| 62 | { | 65 | { |
| @@ -142,6 +145,10 @@ struct cxgbi_device *cxgbi_device_register(unsigned int extra, | |||
| 142 | list_add_tail(&cdev->list_head, &cdev_list); | 145 | list_add_tail(&cdev->list_head, &cdev_list); |
| 143 | mutex_unlock(&cdev_mutex); | 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 | log_debug(1 << CXGBI_DBG_DEV, | 152 | log_debug(1 << CXGBI_DBG_DEV, |
| 146 | "cdev 0x%p, p# %u.\n", cdev, nports); | 153 | "cdev 0x%p, p# %u.\n", cdev, nports); |
| 147 | return cdev; | 154 | return cdev; |
| @@ -153,9 +160,16 @@ void cxgbi_device_unregister(struct cxgbi_device *cdev) | |||
| 153 | log_debug(1 << CXGBI_DBG_DEV, | 160 | log_debug(1 << CXGBI_DBG_DEV, |
| 154 | "cdev 0x%p, p# %u,%s.\n", | 161 | "cdev 0x%p, p# %u,%s.\n", |
| 155 | cdev, cdev->nports, cdev->nports ? cdev->ports[0]->name : ""); | 162 | cdev, cdev->nports, cdev->nports ? cdev->ports[0]->name : ""); |
| 163 | |||
| 156 | mutex_lock(&cdev_mutex); | 164 | mutex_lock(&cdev_mutex); |
| 157 | list_del(&cdev->list_head); | 165 | list_del(&cdev->list_head); |
| 158 | mutex_unlock(&cdev_mutex); | 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 | cxgbi_device_destroy(cdev); | 173 | cxgbi_device_destroy(cdev); |
| 160 | } | 174 | } |
| 161 | EXPORT_SYMBOL_GPL(cxgbi_device_unregister); | 175 | EXPORT_SYMBOL_GPL(cxgbi_device_unregister); |
| @@ -167,12 +181,9 @@ void cxgbi_device_unregister_all(unsigned int flag) | |||
| 167 | mutex_lock(&cdev_mutex); | 181 | mutex_lock(&cdev_mutex); |
| 168 | list_for_each_entry_safe(cdev, tmp, &cdev_list, list_head) { | 182 | list_for_each_entry_safe(cdev, tmp, &cdev_list, list_head) { |
| 169 | if ((cdev->flags & flag) == flag) { | 183 | if ((cdev->flags & flag) == flag) { |
| 170 | log_debug(1 << CXGBI_DBG_DEV, | 184 | mutex_unlock(&cdev_mutex); |
| 171 | "cdev 0x%p, p# %u,%s.\n", | 185 | cxgbi_device_unregister(cdev); |
| 172 | cdev, cdev->nports, cdev->nports ? | 186 | mutex_lock(&cdev_mutex); |
| 173 | cdev->ports[0]->name : ""); | ||
| 174 | list_del(&cdev->list_head); | ||
| 175 | cxgbi_device_destroy(cdev); | ||
| 176 | } | 187 | } |
| 177 | } | 188 | } |
| 178 | mutex_unlock(&cdev_mutex); | 189 | mutex_unlock(&cdev_mutex); |
| @@ -191,6 +202,7 @@ struct cxgbi_device *cxgbi_device_find_by_lldev(void *lldev) | |||
| 191 | } | 202 | } |
| 192 | } | 203 | } |
| 193 | mutex_unlock(&cdev_mutex); | 204 | mutex_unlock(&cdev_mutex); |
| 205 | |||
| 194 | log_debug(1 << CXGBI_DBG_DEV, | 206 | log_debug(1 << CXGBI_DBG_DEV, |
| 195 | "lldev 0x%p, NO match found.\n", lldev); | 207 | "lldev 0x%p, NO match found.\n", lldev); |
| 196 | return NULL; | 208 | return NULL; |
| @@ -230,6 +242,39 @@ struct cxgbi_device *cxgbi_device_find_by_netdev(struct net_device *ndev, | |||
| 230 | } | 242 | } |
| 231 | EXPORT_SYMBOL_GPL(cxgbi_device_find_by_netdev); | 243 | EXPORT_SYMBOL_GPL(cxgbi_device_find_by_netdev); |
| 232 | 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); | ||
| 277 | |||
| 233 | static struct cxgbi_device *cxgbi_device_find_by_mac(struct net_device *ndev, | 278 | static struct cxgbi_device *cxgbi_device_find_by_mac(struct net_device *ndev, |
| 234 | int *port) | 279 | int *port) |
| 235 | { | 280 | { |
diff --git a/drivers/scsi/cxgbi/libcxgbi.h b/drivers/scsi/cxgbi/libcxgbi.h index b3e6e7541cc5..1d98fad6a0ab 100644 --- a/drivers/scsi/cxgbi/libcxgbi.h +++ b/drivers/scsi/cxgbi/libcxgbi.h | |||
| @@ -527,6 +527,7 @@ struct cxgbi_ports_map { | |||
| 527 | #define CXGBI_FLAG_IPV4_SET 0x10 | 527 | #define CXGBI_FLAG_IPV4_SET 0x10 |
| 528 | struct cxgbi_device { | 528 | struct cxgbi_device { |
| 529 | struct list_head list_head; | 529 | struct list_head list_head; |
| 530 | struct list_head rcu_node; | ||
| 530 | unsigned int flags; | 531 | unsigned int flags; |
| 531 | struct net_device **ports; | 532 | struct net_device **ports; |
| 532 | void *lldev; | 533 | void *lldev; |
| @@ -709,6 +710,8 @@ void cxgbi_device_unregister(struct cxgbi_device *); | |||
| 709 | void cxgbi_device_unregister_all(unsigned int flag); | 710 | void cxgbi_device_unregister_all(unsigned int flag); |
| 710 | struct cxgbi_device *cxgbi_device_find_by_lldev(void *); | 711 | struct cxgbi_device *cxgbi_device_find_by_lldev(void *); |
| 711 | struct cxgbi_device *cxgbi_device_find_by_netdev(struct net_device *, int *); | 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 | int cxgbi_hbas_add(struct cxgbi_device *, u64, unsigned int, | 715 | int cxgbi_hbas_add(struct cxgbi_device *, u64, unsigned int, |
| 713 | struct scsi_host_template *, | 716 | struct scsi_host_template *, |
| 714 | struct scsi_transport_template *); | 717 | struct scsi_transport_template *); |
diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index 3f42785f653c..9bfa7252f7f9 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c | |||
| @@ -970,6 +970,13 @@ static struct scsi_host_template uas_host_template = { | |||
| 970 | .cmd_per_lun = 1, /* until we override it */ | 970 | .cmd_per_lun = 1, /* until we override it */ |
| 971 | .skip_settle_delay = 1, | 971 | .skip_settle_delay = 1, |
| 972 | .ordered_tag = 1, | 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 | #define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ | 982 | #define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ |
