summaryrefslogtreecommitdiff
path: root/drivers/net/cxgb3/l2t.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-09-28 08:23:39 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2011-09-28 08:23:39 -0700
commit07117e305487b0d4251a97d3529fa2c7d930d36a (patch)
treec1af2ba9d950ba397bc82b9d1a70c34953c30a5f /drivers/net/cxgb3/l2t.c
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/net/cxgb3/l2t.c')
-rw-r--r--drivers/net/cxgb3/l2t.c15
1 files changed, 12 insertions, 3 deletions
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)
struct l2t_entry *t3_l2t_get(struct t3cdev *cdev, struct neighbour *neigh,
struct net_device *dev)
{
- struct l2t_entry *e;
- struct l2t_data *d = L2DATA(cdev);
+ struct l2t_entry *e = NULL;
+ struct l2t_data *d;
+ int hash;
u32 addr = *(u32 *) neigh->primary_key;
int ifidx = neigh->dev->ifindex;
- int hash = arp_hash(addr, ifidx, d);
struct port_info *p = netdev_priv(dev);
int smt_idx = p->port_id;
+ rcu_read_lock();
+ d = L2DATA(cdev);
+ if (!d)
+ goto done_rcu;
+
+ hash = arp_hash(addr, ifidx, d);
+
write_lock_bh(&d->lock);
for (e = d->l2tab[hash].first; e; e = e->next)
if (e->addr == addr && e->ifindex == ifidx &&
@@ -338,6 +345,8 @@ struct l2t_entry *t3_l2t_get(struct t3cdev *cdev, struct neighbour *neigh,
}
done:
write_unlock_bh(&d->lock);
+done_rcu:
+ rcu_read_unlock();
return e;
}