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
This commit is contained in:
@@ -1647,7 +1647,7 @@ static int cxgbi_inet6addr_handler(struct notifier_block *this,
|
|||||||
if (event_dev->priv_flags & IFF_802_1Q_VLAN)
|
if (event_dev->priv_flags & IFF_802_1Q_VLAN)
|
||||||
event_dev = vlan_dev_real_dev(event_dev);
|
event_dev = vlan_dev_real_dev(event_dev);
|
||||||
|
|
||||||
cdev = cxgbi_device_find_by_netdev(event_dev, NULL);
|
cdev = cxgbi_device_find_by_netdev_rcu(event_dev, NULL);
|
||||||
|
|
||||||
if (!cdev)
|
if (!cdev)
|
||||||
return ret;
|
return ret;
|
||||||
|
@@ -57,6 +57,9 @@ MODULE_PARM_DESC(dbg_level, "libiscsi debug level (default=0)");
|
|||||||
static LIST_HEAD(cdev_list);
|
static LIST_HEAD(cdev_list);
|
||||||
static DEFINE_MUTEX(cdev_mutex);
|
static DEFINE_MUTEX(cdev_mutex);
|
||||||
|
|
||||||
|
static LIST_HEAD(cdev_rcu_list);
|
||||||
|
static DEFINE_SPINLOCK(cdev_rcu_lock);
|
||||||
|
|
||||||
int cxgbi_device_portmap_create(struct cxgbi_device *cdev, unsigned int base,
|
int cxgbi_device_portmap_create(struct cxgbi_device *cdev, unsigned int base,
|
||||||
unsigned int max_conn)
|
unsigned int max_conn)
|
||||||
{
|
{
|
||||||
@@ -142,6 +145,10 @@ struct cxgbi_device *cxgbi_device_register(unsigned int extra,
|
|||||||
list_add_tail(&cdev->list_head, &cdev_list);
|
list_add_tail(&cdev->list_head, &cdev_list);
|
||||||
mutex_unlock(&cdev_mutex);
|
mutex_unlock(&cdev_mutex);
|
||||||
|
|
||||||
|
spin_lock(&cdev_rcu_lock);
|
||||||
|
list_add_tail_rcu(&cdev->rcu_node, &cdev_rcu_list);
|
||||||
|
spin_unlock(&cdev_rcu_lock);
|
||||||
|
|
||||||
log_debug(1 << CXGBI_DBG_DEV,
|
log_debug(1 << CXGBI_DBG_DEV,
|
||||||
"cdev 0x%p, p# %u.\n", cdev, nports);
|
"cdev 0x%p, p# %u.\n", cdev, nports);
|
||||||
return cdev;
|
return cdev;
|
||||||
@@ -153,9 +160,16 @@ void cxgbi_device_unregister(struct cxgbi_device *cdev)
|
|||||||
log_debug(1 << CXGBI_DBG_DEV,
|
log_debug(1 << CXGBI_DBG_DEV,
|
||||||
"cdev 0x%p, p# %u,%s.\n",
|
"cdev 0x%p, p# %u,%s.\n",
|
||||||
cdev, cdev->nports, cdev->nports ? cdev->ports[0]->name : "");
|
cdev, cdev->nports, cdev->nports ? cdev->ports[0]->name : "");
|
||||||
|
|
||||||
mutex_lock(&cdev_mutex);
|
mutex_lock(&cdev_mutex);
|
||||||
list_del(&cdev->list_head);
|
list_del(&cdev->list_head);
|
||||||
mutex_unlock(&cdev_mutex);
|
mutex_unlock(&cdev_mutex);
|
||||||
|
|
||||||
|
spin_lock(&cdev_rcu_lock);
|
||||||
|
list_del_rcu(&cdev->rcu_node);
|
||||||
|
spin_unlock(&cdev_rcu_lock);
|
||||||
|
synchronize_rcu();
|
||||||
|
|
||||||
cxgbi_device_destroy(cdev);
|
cxgbi_device_destroy(cdev);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(cxgbi_device_unregister);
|
EXPORT_SYMBOL_GPL(cxgbi_device_unregister);
|
||||||
@@ -167,12 +181,9 @@ void cxgbi_device_unregister_all(unsigned int flag)
|
|||||||
mutex_lock(&cdev_mutex);
|
mutex_lock(&cdev_mutex);
|
||||||
list_for_each_entry_safe(cdev, tmp, &cdev_list, list_head) {
|
list_for_each_entry_safe(cdev, tmp, &cdev_list, list_head) {
|
||||||
if ((cdev->flags & flag) == flag) {
|
if ((cdev->flags & flag) == flag) {
|
||||||
log_debug(1 << CXGBI_DBG_DEV,
|
mutex_unlock(&cdev_mutex);
|
||||||
"cdev 0x%p, p# %u,%s.\n",
|
cxgbi_device_unregister(cdev);
|
||||||
cdev, cdev->nports, cdev->nports ?
|
mutex_lock(&cdev_mutex);
|
||||||
cdev->ports[0]->name : "");
|
|
||||||
list_del(&cdev->list_head);
|
|
||||||
cxgbi_device_destroy(cdev);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mutex_unlock(&cdev_mutex);
|
mutex_unlock(&cdev_mutex);
|
||||||
@@ -191,6 +202,7 @@ struct cxgbi_device *cxgbi_device_find_by_lldev(void *lldev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
mutex_unlock(&cdev_mutex);
|
mutex_unlock(&cdev_mutex);
|
||||||
|
|
||||||
log_debug(1 << CXGBI_DBG_DEV,
|
log_debug(1 << CXGBI_DBG_DEV,
|
||||||
"lldev 0x%p, NO match found.\n", lldev);
|
"lldev 0x%p, NO match found.\n", lldev);
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -230,6 +242,39 @@ struct cxgbi_device *cxgbi_device_find_by_netdev(struct net_device *ndev,
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(cxgbi_device_find_by_netdev);
|
EXPORT_SYMBOL_GPL(cxgbi_device_find_by_netdev);
|
||||||
|
|
||||||
|
struct cxgbi_device *cxgbi_device_find_by_netdev_rcu(struct net_device *ndev,
|
||||||
|
int *port)
|
||||||
|
{
|
||||||
|
struct net_device *vdev = NULL;
|
||||||
|
struct cxgbi_device *cdev;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (ndev->priv_flags & IFF_802_1Q_VLAN) {
|
||||||
|
vdev = ndev;
|
||||||
|
ndev = vlan_dev_real_dev(ndev);
|
||||||
|
pr_info("vlan dev %s -> %s.\n", vdev->name, ndev->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
rcu_read_lock();
|
||||||
|
list_for_each_entry_rcu(cdev, &cdev_rcu_list, rcu_node) {
|
||||||
|
for (i = 0; i < cdev->nports; i++) {
|
||||||
|
if (ndev == cdev->ports[i]) {
|
||||||
|
cdev->hbas[i]->vdev = vdev;
|
||||||
|
rcu_read_unlock();
|
||||||
|
if (port)
|
||||||
|
*port = i;
|
||||||
|
return cdev;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rcu_read_unlock();
|
||||||
|
|
||||||
|
log_debug(1 << CXGBI_DBG_DEV,
|
||||||
|
"ndev 0x%p, %s, NO match found.\n", ndev, ndev->name);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(cxgbi_device_find_by_netdev_rcu);
|
||||||
|
|
||||||
static struct cxgbi_device *cxgbi_device_find_by_mac(struct net_device *ndev,
|
static struct cxgbi_device *cxgbi_device_find_by_mac(struct net_device *ndev,
|
||||||
int *port)
|
int *port)
|
||||||
{
|
{
|
||||||
|
@@ -527,6 +527,7 @@ struct cxgbi_ports_map {
|
|||||||
#define CXGBI_FLAG_IPV4_SET 0x10
|
#define CXGBI_FLAG_IPV4_SET 0x10
|
||||||
struct cxgbi_device {
|
struct cxgbi_device {
|
||||||
struct list_head list_head;
|
struct list_head list_head;
|
||||||
|
struct list_head rcu_node;
|
||||||
unsigned int flags;
|
unsigned int flags;
|
||||||
struct net_device **ports;
|
struct net_device **ports;
|
||||||
void *lldev;
|
void *lldev;
|
||||||
@@ -709,6 +710,8 @@ void cxgbi_device_unregister(struct cxgbi_device *);
|
|||||||
void cxgbi_device_unregister_all(unsigned int flag);
|
void cxgbi_device_unregister_all(unsigned int flag);
|
||||||
struct cxgbi_device *cxgbi_device_find_by_lldev(void *);
|
struct cxgbi_device *cxgbi_device_find_by_lldev(void *);
|
||||||
struct cxgbi_device *cxgbi_device_find_by_netdev(struct net_device *, int *);
|
struct cxgbi_device *cxgbi_device_find_by_netdev(struct net_device *, int *);
|
||||||
|
struct cxgbi_device *cxgbi_device_find_by_netdev_rcu(struct net_device *,
|
||||||
|
int *);
|
||||||
int cxgbi_hbas_add(struct cxgbi_device *, u64, unsigned int,
|
int cxgbi_hbas_add(struct cxgbi_device *, u64, unsigned int,
|
||||||
struct scsi_host_template *,
|
struct scsi_host_template *,
|
||||||
struct scsi_transport_template *);
|
struct scsi_transport_template *);
|
||||||
|
@@ -970,6 +970,13 @@ static struct scsi_host_template uas_host_template = {
|
|||||||
.cmd_per_lun = 1, /* until we override it */
|
.cmd_per_lun = 1, /* until we override it */
|
||||||
.skip_settle_delay = 1,
|
.skip_settle_delay = 1,
|
||||||
.ordered_tag = 1,
|
.ordered_tag = 1,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The uas drivers expects tags not to be bigger than the maximum
|
||||||
|
* per-device queue depth, which is not true with the blk-mq tag
|
||||||
|
* allocator.
|
||||||
|
*/
|
||||||
|
.disable_blk_mq = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
|
#define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
|
||||||
|
Reference in New Issue
Block a user