aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-09-28 11:23:39 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-09-28 11:23:39 -0400
commit07117e305487b0d4251a97d3529fa2c7d930d36a (patch)
treec1af2ba9d950ba397bc82b9d1a70c34953c30a5f /drivers
parentc54a06d45a937750e76df2f91e940f82c07c5bf7 (diff)
parent96067723e46b0dd24ae7b934085ab4eff4d26a1b (diff)
Merge git://bedivere.hansenpartnership.com/git/scsi-rc-fixes-2.6
* git://bedivere.hansenpartnership.com/git/scsi-rc-fixes-2.6: [SCSI] 3w-9xxx: fix iommu_iova leak [SCSI] cxgb3i: convert cdev->l2opt to use rcu to prevent NULL dereference [SCSI] scsi: qla4xxx needs libiscsi.o [SCSI] libsas: fix failure to revalidate domain for anything but the first expander child. [SCSI] aacraid: reset should disable MSI interrupt
Diffstat (limited to 'drivers')
-rw-r--r--drivers/infiniband/hw/cxgb3/iwch_cm.c10
-rw-r--r--drivers/net/cxgb3/cxgb3_offload.c23
-rw-r--r--drivers/net/cxgb3/l2t.c15
-rw-r--r--drivers/net/cxgb3/l2t.h16
-rw-r--r--drivers/scsi/3w-9xxx.c2
-rw-r--r--drivers/scsi/Makefile2
-rw-r--r--drivers/scsi/aacraid/commsup.c2
-rw-r--r--drivers/scsi/cxgbi/cxgb3i/cxgb3i.c2
-rw-r--r--drivers/scsi/libsas/sas_expander.c2
9 files changed, 54 insertions, 20 deletions
diff --git a/drivers/infiniband/hw/cxgb3/iwch_cm.c b/drivers/infiniband/hw/cxgb3/iwch_cm.c
index 17bf9d95463c..6cd642aaa4de 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_cm.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_cm.c
@@ -287,7 +287,7 @@ void __free_ep(struct kref *kref)
287 if (test_bit(RELEASE_RESOURCES, &ep->com.flags)) { 287 if (test_bit(RELEASE_RESOURCES, &ep->com.flags)) {
288 cxgb3_remove_tid(ep->com.tdev, (void *)ep, ep->hwtid); 288 cxgb3_remove_tid(ep->com.tdev, (void *)ep, ep->hwtid);
289 dst_release(ep->dst); 289 dst_release(ep->dst);
290 l2t_release(L2DATA(ep->com.tdev), ep->l2t); 290 l2t_release(ep->com.tdev, ep->l2t);
291 } 291 }
292 kfree(ep); 292 kfree(ep);
293} 293}
@@ -1178,7 +1178,7 @@ static int act_open_rpl(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
1178 release_tid(ep->com.tdev, GET_TID(rpl), NULL); 1178 release_tid(ep->com.tdev, GET_TID(rpl), NULL);
1179 cxgb3_free_atid(ep->com.tdev, ep->atid); 1179 cxgb3_free_atid(ep->com.tdev, ep->atid);
1180 dst_release(ep->dst); 1180 dst_release(ep->dst);
1181 l2t_release(L2DATA(ep->com.tdev), ep->l2t); 1181 l2t_release(ep->com.tdev, ep->l2t);
1182 put_ep(&ep->com); 1182 put_ep(&ep->com);
1183 return CPL_RET_BUF_DONE; 1183 return CPL_RET_BUF_DONE;
1184} 1184}
@@ -1377,7 +1377,7 @@ static int pass_accept_req(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
1377 if (!child_ep) { 1377 if (!child_ep) {
1378 printk(KERN_ERR MOD "%s - failed to allocate ep entry!\n", 1378 printk(KERN_ERR MOD "%s - failed to allocate ep entry!\n",
1379 __func__); 1379 __func__);
1380 l2t_release(L2DATA(tdev), l2t); 1380 l2t_release(tdev, l2t);
1381 dst_release(dst); 1381 dst_release(dst);
1382 goto reject; 1382 goto reject;
1383 } 1383 }
@@ -1956,7 +1956,7 @@ int iwch_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
1956 if (!err) 1956 if (!err)
1957 goto out; 1957 goto out;
1958 1958
1959 l2t_release(L2DATA(h->rdev.t3cdev_p), ep->l2t); 1959 l2t_release(h->rdev.t3cdev_p, ep->l2t);
1960fail4: 1960fail4:
1961 dst_release(ep->dst); 1961 dst_release(ep->dst);
1962fail3: 1962fail3:
@@ -2127,7 +2127,7 @@ int iwch_ep_redirect(void *ctx, struct dst_entry *old, struct dst_entry *new,
2127 PDBG("%s ep %p redirect to dst %p l2t %p\n", __func__, ep, new, 2127 PDBG("%s ep %p redirect to dst %p l2t %p\n", __func__, ep, new,
2128 l2t); 2128 l2t);
2129 dst_hold(new); 2129 dst_hold(new);
2130 l2t_release(L2DATA(ep->com.tdev), ep->l2t); 2130 l2t_release(ep->com.tdev, ep->l2t);
2131 ep->l2t = l2t; 2131 ep->l2t = l2t;
2132 dst_release(old); 2132 dst_release(old);
2133 ep->dst = new; 2133 ep->dst = new;
diff --git a/drivers/net/cxgb3/cxgb3_offload.c b/drivers/net/cxgb3/cxgb3_offload.c
index 805076c54f1b..da5a5d9b8aff 100644
--- a/drivers/net/cxgb3/cxgb3_offload.c
+++ b/drivers/net/cxgb3/cxgb3_offload.c
@@ -1146,12 +1146,14 @@ static void cxgb_redirect(struct dst_entry *old, struct dst_entry *new)
1146 if (te && te->ctx && te->client && te->client->redirect) { 1146 if (te && te->ctx && te->client && te->client->redirect) {
1147 update_tcb = te->client->redirect(te->ctx, old, new, e); 1147 update_tcb = te->client->redirect(te->ctx, old, new, e);
1148 if (update_tcb) { 1148 if (update_tcb) {
1149 rcu_read_lock();
1149 l2t_hold(L2DATA(tdev), e); 1150 l2t_hold(L2DATA(tdev), e);
1151 rcu_read_unlock();
1150 set_l2t_ix(tdev, tid, e); 1152 set_l2t_ix(tdev, tid, e);
1151 } 1153 }
1152 } 1154 }
1153 } 1155 }
1154 l2t_release(L2DATA(tdev), e); 1156 l2t_release(tdev, e);
1155} 1157}
1156 1158
1157/* 1159/*
@@ -1264,7 +1266,7 @@ int cxgb3_offload_activate(struct adapter *adapter)
1264 goto out_free; 1266 goto out_free;
1265 1267
1266 err = -ENOMEM; 1268 err = -ENOMEM;
1267 L2DATA(dev) = t3_init_l2t(l2t_capacity); 1269 RCU_INIT_POINTER(dev->l2opt, t3_init_l2t(l2t_capacity));
1268 if (!L2DATA(dev)) 1270 if (!L2DATA(dev))
1269 goto out_free; 1271 goto out_free;
1270 1272
@@ -1298,16 +1300,24 @@ int cxgb3_offload_activate(struct adapter *adapter)
1298 1300
1299out_free_l2t: 1301out_free_l2t:
1300 t3_free_l2t(L2DATA(dev)); 1302 t3_free_l2t(L2DATA(dev));
1301 L2DATA(dev) = NULL; 1303 rcu_assign_pointer(dev->l2opt, NULL);
1302out_free: 1304out_free:
1303 kfree(t); 1305 kfree(t);
1304 return err; 1306 return err;
1305} 1307}
1306 1308
1309static void clean_l2_data(struct rcu_head *head)
1310{
1311 struct l2t_data *d = container_of(head, struct l2t_data, rcu_head);
1312 t3_free_l2t(d);
1313}
1314
1315
1307void cxgb3_offload_deactivate(struct adapter *adapter) 1316void cxgb3_offload_deactivate(struct adapter *adapter)
1308{ 1317{
1309 struct t3cdev *tdev = &adapter->tdev; 1318 struct t3cdev *tdev = &adapter->tdev;
1310 struct t3c_data *t = T3C_DATA(tdev); 1319 struct t3c_data *t = T3C_DATA(tdev);
1320 struct l2t_data *d;
1311 1321
1312 remove_adapter(adapter); 1322 remove_adapter(adapter);
1313 if (list_empty(&adapter_list)) 1323 if (list_empty(&adapter_list))
@@ -1315,8 +1325,11 @@ void cxgb3_offload_deactivate(struct adapter *adapter)
1315 1325
1316 free_tid_maps(&t->tid_maps); 1326 free_tid_maps(&t->tid_maps);
1317 T3C_DATA(tdev) = NULL; 1327 T3C_DATA(tdev) = NULL;
1318 t3_free_l2t(L2DATA(tdev)); 1328 rcu_read_lock();
1319 L2DATA(tdev) = NULL; 1329 d = L2DATA(tdev);
1330 rcu_read_unlock();
1331 rcu_assign_pointer(tdev->l2opt, NULL);
1332 call_rcu(&d->rcu_head, clean_l2_data);
1320 if (t->nofail_skb) 1333 if (t->nofail_skb)
1321 kfree_skb(t->nofail_skb); 1334 kfree_skb(t->nofail_skb);
1322 kfree(t); 1335 kfree(t);
diff --git a/drivers/net/cxgb3/l2t.c b/drivers/net/cxgb3/l2t.c
index f452c4003253..41540978a173 100644
--- a/drivers/net/cxgb3/l2t.c
+++ b/drivers/net/cxgb3/l2t.c
@@ -300,14 +300,21 @@ static inline void reuse_entry(struct l2t_entry *e, struct neighbour *neigh)
300struct l2t_entry *t3_l2t_get(struct t3cdev *cdev, struct neighbour *neigh, 300struct l2t_entry *t3_l2t_get(struct t3cdev *cdev, struct neighbour *neigh,
301 struct net_device *dev) 301 struct net_device *dev)
302{ 302{
303 struct l2t_entry *e; 303 struct l2t_entry *e = NULL;
304 struct l2t_data *d = L2DATA(cdev); 304 struct l2t_data *d;
305 int hash;
305 u32 addr = *(u32 *) neigh->primary_key; 306 u32 addr = *(u32 *) neigh->primary_key;
306 int ifidx = neigh->dev->ifindex; 307 int ifidx = neigh->dev->ifindex;
307 int hash = arp_hash(addr, ifidx, d);
308 struct port_info *p = netdev_priv(dev); 308 struct port_info *p = netdev_priv(dev);
309 int smt_idx = p->port_id; 309 int smt_idx = p->port_id;
310 310
311 rcu_read_lock();
312 d = L2DATA(cdev);
313 if (!d)
314 goto done_rcu;
315
316 hash = arp_hash(addr, ifidx, d);
317
311 write_lock_bh(&d->lock); 318 write_lock_bh(&d->lock);
312 for (e = d->l2tab[hash].first; e; e = e->next) 319 for (e = d->l2tab[hash].first; e; e = e->next)
313 if (e->addr == addr && e->ifindex == ifidx && 320 if (e->addr == addr && e->ifindex == ifidx &&
@@ -338,6 +345,8 @@ struct l2t_entry *t3_l2t_get(struct t3cdev *cdev, struct neighbour *neigh,
338 } 345 }
339done: 346done:
340 write_unlock_bh(&d->lock); 347 write_unlock_bh(&d->lock);
348done_rcu:
349 rcu_read_unlock();
341 return e; 350 return e;
342} 351}
343 352
diff --git a/drivers/net/cxgb3/l2t.h b/drivers/net/cxgb3/l2t.h
index 7a12d52ed4fc..c5f54796e2cb 100644
--- a/drivers/net/cxgb3/l2t.h
+++ b/drivers/net/cxgb3/l2t.h
@@ -76,6 +76,7 @@ struct l2t_data {
76 atomic_t nfree; /* number of free entries */ 76 atomic_t nfree; /* number of free entries */
77 rwlock_t lock; 77 rwlock_t lock;
78 struct l2t_entry l2tab[0]; 78 struct l2t_entry l2tab[0];
79 struct rcu_head rcu_head; /* to handle rcu cleanup */
79}; 80};
80 81
81typedef void (*arp_failure_handler_func)(struct t3cdev * dev, 82typedef void (*arp_failure_handler_func)(struct t3cdev * dev,
@@ -99,7 +100,7 @@ static inline void set_arp_failure_handler(struct sk_buff *skb,
99/* 100/*
100 * Getting to the L2 data from an offload device. 101 * Getting to the L2 data from an offload device.
101 */ 102 */
102#define L2DATA(dev) ((dev)->l2opt) 103#define L2DATA(cdev) (rcu_dereference((cdev)->l2opt))
103 104
104#define W_TCB_L2T_IX 0 105#define W_TCB_L2T_IX 0
105#define S_TCB_L2T_IX 7 106#define S_TCB_L2T_IX 7
@@ -126,15 +127,22 @@ static inline int l2t_send(struct t3cdev *dev, struct sk_buff *skb,
126 return t3_l2t_send_slow(dev, skb, e); 127 return t3_l2t_send_slow(dev, skb, e);
127} 128}
128 129
129static inline void l2t_release(struct l2t_data *d, struct l2t_entry *e) 130static inline void l2t_release(struct t3cdev *t, struct l2t_entry *e)
130{ 131{
131 if (atomic_dec_and_test(&e->refcnt)) 132 struct l2t_data *d;
133
134 rcu_read_lock();
135 d = L2DATA(t);
136
137 if (atomic_dec_and_test(&e->refcnt) && d)
132 t3_l2e_free(d, e); 138 t3_l2e_free(d, e);
139
140 rcu_read_unlock();
133} 141}
134 142
135static inline void l2t_hold(struct l2t_data *d, struct l2t_entry *e) 143static inline void l2t_hold(struct l2t_data *d, struct l2t_entry *e)
136{ 144{
137 if (atomic_add_return(1, &e->refcnt) == 1) /* 0 -> 1 transition */ 145 if (d && atomic_add_return(1, &e->refcnt) == 1) /* 0 -> 1 transition */
138 atomic_dec(&d->nfree); 146 atomic_dec(&d->nfree);
139} 147}
140 148
diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c
index b7bd5b0cc7aa..3868ab2397c6 100644
--- a/drivers/scsi/3w-9xxx.c
+++ b/drivers/scsi/3w-9xxx.c
@@ -1800,10 +1800,12 @@ static int twa_scsi_queue_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_
1800 switch (retval) { 1800 switch (retval) {
1801 case SCSI_MLQUEUE_HOST_BUSY: 1801 case SCSI_MLQUEUE_HOST_BUSY:
1802 twa_free_request_id(tw_dev, request_id); 1802 twa_free_request_id(tw_dev, request_id);
1803 twa_unmap_scsi_data(tw_dev, request_id);
1803 break; 1804 break;
1804 case 1: 1805 case 1:
1805 tw_dev->state[request_id] = TW_S_COMPLETED; 1806 tw_dev->state[request_id] = TW_S_COMPLETED;
1806 twa_free_request_id(tw_dev, request_id); 1807 twa_free_request_id(tw_dev, request_id);
1808 twa_unmap_scsi_data(tw_dev, request_id);
1807 SCpnt->result = (DID_ERROR << 16); 1809 SCpnt->result = (DID_ERROR << 16);
1808 done(SCpnt); 1810 done(SCpnt);
1809 retval = 0; 1811 retval = 0;
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
index 3c08f5352b2d..6153a66a8a31 100644
--- a/drivers/scsi/Makefile
+++ b/drivers/scsi/Makefile
@@ -88,7 +88,7 @@ obj-$(CONFIG_SCSI_QLOGIC_FAS) += qlogicfas408.o qlogicfas.o
88obj-$(CONFIG_PCMCIA_QLOGIC) += qlogicfas408.o 88obj-$(CONFIG_PCMCIA_QLOGIC) += qlogicfas408.o
89obj-$(CONFIG_SCSI_QLOGIC_1280) += qla1280.o 89obj-$(CONFIG_SCSI_QLOGIC_1280) += qla1280.o
90obj-$(CONFIG_SCSI_QLA_FC) += qla2xxx/ 90obj-$(CONFIG_SCSI_QLA_FC) += qla2xxx/
91obj-$(CONFIG_SCSI_QLA_ISCSI) += qla4xxx/ 91obj-$(CONFIG_SCSI_QLA_ISCSI) += libiscsi.o qla4xxx/
92obj-$(CONFIG_SCSI_LPFC) += lpfc/ 92obj-$(CONFIG_SCSI_LPFC) += lpfc/
93obj-$(CONFIG_SCSI_BFA_FC) += bfa/ 93obj-$(CONFIG_SCSI_BFA_FC) += bfa/
94obj-$(CONFIG_SCSI_PAS16) += pas16.o 94obj-$(CONFIG_SCSI_PAS16) += pas16.o
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
index e7d0d47b9185..e5f2d7d9002e 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -1283,6 +1283,8 @@ static int _aac_reset_adapter(struct aac_dev *aac, int forced)
1283 kfree(aac->queues); 1283 kfree(aac->queues);
1284 aac->queues = NULL; 1284 aac->queues = NULL;
1285 free_irq(aac->pdev->irq, aac); 1285 free_irq(aac->pdev->irq, aac);
1286 if (aac->msi)
1287 pci_disable_msi(aac->pdev);
1286 kfree(aac->fsa_dev); 1288 kfree(aac->fsa_dev);
1287 aac->fsa_dev = NULL; 1289 aac->fsa_dev = NULL;
1288 quirks = aac_get_driver_ident(index)->quirks; 1290 quirks = aac_get_driver_ident(index)->quirks;
diff --git a/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c b/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c
index bd22041e2789..f58644850333 100644
--- a/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c
+++ b/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c
@@ -913,7 +913,7 @@ static void l2t_put(struct cxgbi_sock *csk)
913 struct t3cdev *t3dev = (struct t3cdev *)csk->cdev->lldev; 913 struct t3cdev *t3dev = (struct t3cdev *)csk->cdev->lldev;
914 914
915 if (csk->l2t) { 915 if (csk->l2t) {
916 l2t_release(L2DATA(t3dev), csk->l2t); 916 l2t_release(t3dev, csk->l2t);
917 csk->l2t = NULL; 917 csk->l2t = NULL;
918 cxgbi_sock_put(csk); 918 cxgbi_sock_put(csk);
919 } 919 }
diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c
index f84084bba2f0..c9e3dc024bc3 100644
--- a/drivers/scsi/libsas/sas_expander.c
+++ b/drivers/scsi/libsas/sas_expander.c
@@ -1721,7 +1721,7 @@ static int sas_find_bcast_dev(struct domain_device *dev,
1721 list_for_each_entry(ch, &ex->children, siblings) { 1721 list_for_each_entry(ch, &ex->children, siblings) {
1722 if (ch->dev_type == EDGE_DEV || ch->dev_type == FANOUT_DEV) { 1722 if (ch->dev_type == EDGE_DEV || ch->dev_type == FANOUT_DEV) {
1723 res = sas_find_bcast_dev(ch, src_dev); 1723 res = sas_find_bcast_dev(ch, src_dev);
1724 if (src_dev) 1724 if (*src_dev)
1725 return res; 1725 return res;
1726 } 1726 }
1727 } 1727 }