Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 264155
b: refs/heads/master
c: e48f129
h: refs/heads/master
i:
  264153: a78580a
  264151: 1d5cfbb
v: v3
  • Loading branch information
Neil Horman authored and James Bottomley committed Sep 26, 2011
1 parent 9651b31 commit 895e042
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 19 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 3538a001ea7db13fa1be2966b71f69d808acff01
refs/heads/master: e48f129c2f200dde8899f6ea5c6e7173674fc482
10 changes: 5 additions & 5 deletions trunk/drivers/infiniband/hw/cxgb3/iwch_cm.c
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ void __free_ep(struct kref *kref)
if (test_bit(RELEASE_RESOURCES, &ep->com.flags)) {
cxgb3_remove_tid(ep->com.tdev, (void *)ep, ep->hwtid);
dst_release(ep->dst);
l2t_release(L2DATA(ep->com.tdev), ep->l2t);
l2t_release(ep->com.tdev, ep->l2t);
}
kfree(ep);
}
Expand Down Expand Up @@ -1178,7 +1178,7 @@ static int act_open_rpl(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
release_tid(ep->com.tdev, GET_TID(rpl), NULL);
cxgb3_free_atid(ep->com.tdev, ep->atid);
dst_release(ep->dst);
l2t_release(L2DATA(ep->com.tdev), ep->l2t);
l2t_release(ep->com.tdev, ep->l2t);
put_ep(&ep->com);
return CPL_RET_BUF_DONE;
}
Expand Down Expand Up @@ -1377,7 +1377,7 @@ static int pass_accept_req(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
if (!child_ep) {
printk(KERN_ERR MOD "%s - failed to allocate ep entry!\n",
__func__);
l2t_release(L2DATA(tdev), l2t);
l2t_release(tdev, l2t);
dst_release(dst);
goto reject;
}
Expand Down Expand Up @@ -1956,7 +1956,7 @@ int iwch_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
if (!err)
goto out;

l2t_release(L2DATA(h->rdev.t3cdev_p), ep->l2t);
l2t_release(h->rdev.t3cdev_p, ep->l2t);
fail4:
dst_release(ep->dst);
fail3:
Expand Down Expand Up @@ -2127,7 +2127,7 @@ int iwch_ep_redirect(void *ctx, struct dst_entry *old, struct dst_entry *new,
PDBG("%s ep %p redirect to dst %p l2t %p\n", __func__, ep, new,
l2t);
dst_hold(new);
l2t_release(L2DATA(ep->com.tdev), ep->l2t);
l2t_release(ep->com.tdev, ep->l2t);
ep->l2t = l2t;
dst_release(old);
ep->dst = new;
Expand Down
23 changes: 18 additions & 5 deletions trunk/drivers/net/cxgb3/cxgb3_offload.c
Original file line number Diff line number Diff line change
Expand Up @@ -1146,12 +1146,14 @@ static void cxgb_redirect(struct dst_entry *old, struct dst_entry *new)
if (te && te->ctx && te->client && te->client->redirect) {
update_tcb = te->client->redirect(te->ctx, old, new, e);
if (update_tcb) {
rcu_read_lock();
l2t_hold(L2DATA(tdev), e);
rcu_read_unlock();
set_l2t_ix(tdev, tid, e);
}
}
}
l2t_release(L2DATA(tdev), e);
l2t_release(tdev, e);
}

/*
Expand Down Expand Up @@ -1264,7 +1266,7 @@ int cxgb3_offload_activate(struct adapter *adapter)
goto out_free;

err = -ENOMEM;
L2DATA(dev) = t3_init_l2t(l2t_capacity);
RCU_INIT_POINTER(dev->l2opt, t3_init_l2t(l2t_capacity));
if (!L2DATA(dev))
goto out_free;

Expand Down Expand Up @@ -1298,25 +1300,36 @@ int cxgb3_offload_activate(struct adapter *adapter)

out_free_l2t:
t3_free_l2t(L2DATA(dev));
L2DATA(dev) = NULL;
rcu_assign_pointer(dev->l2opt, NULL);
out_free:
kfree(t);
return err;
}

static void clean_l2_data(struct rcu_head *head)
{
struct l2t_data *d = container_of(head, struct l2t_data, rcu_head);
t3_free_l2t(d);
}


void cxgb3_offload_deactivate(struct adapter *adapter)
{
struct t3cdev *tdev = &adapter->tdev;
struct t3c_data *t = T3C_DATA(tdev);
struct l2t_data *d;

remove_adapter(adapter);
if (list_empty(&adapter_list))
unregister_netevent_notifier(&nb);

free_tid_maps(&t->tid_maps);
T3C_DATA(tdev) = NULL;
t3_free_l2t(L2DATA(tdev));
L2DATA(tdev) = NULL;
rcu_read_lock();
d = L2DATA(tdev);
rcu_read_unlock();
rcu_assign_pointer(tdev->l2opt, NULL);
call_rcu(&d->rcu_head, clean_l2_data);
if (t->nofail_skb)
kfree_skb(t->nofail_skb);
kfree(t);
Expand Down
15 changes: 12 additions & 3 deletions trunk/drivers/net/cxgb3/l2t.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 &&
Expand Down Expand Up @@ -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;
}

Expand Down
16 changes: 12 additions & 4 deletions trunk/drivers/net/cxgb3/l2t.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ struct l2t_data {
atomic_t nfree; /* number of free entries */
rwlock_t lock;
struct l2t_entry l2tab[0];
struct rcu_head rcu_head; /* to handle rcu cleanup */
};

typedef void (*arp_failure_handler_func)(struct t3cdev * dev,
Expand All @@ -99,7 +100,7 @@ static inline void set_arp_failure_handler(struct sk_buff *skb,
/*
* Getting to the L2 data from an offload device.
*/
#define L2DATA(dev) ((dev)->l2opt)
#define L2DATA(cdev) (rcu_dereference((cdev)->l2opt))

#define W_TCB_L2T_IX 0
#define S_TCB_L2T_IX 7
Expand All @@ -126,15 +127,22 @@ static inline int l2t_send(struct t3cdev *dev, struct sk_buff *skb,
return t3_l2t_send_slow(dev, skb, e);
}

static inline void l2t_release(struct l2t_data *d, struct l2t_entry *e)
static inline void l2t_release(struct t3cdev *t, struct l2t_entry *e)
{
if (atomic_dec_and_test(&e->refcnt))
struct l2t_data *d;

rcu_read_lock();
d = L2DATA(t);

if (atomic_dec_and_test(&e->refcnt) && d)
t3_l2e_free(d, e);

rcu_read_unlock();
}

static inline void l2t_hold(struct l2t_data *d, struct l2t_entry *e)
{
if (atomic_add_return(1, &e->refcnt) == 1) /* 0 -> 1 transition */
if (d && atomic_add_return(1, &e->refcnt) == 1) /* 0 -> 1 transition */
atomic_dec(&d->nfree);
}

Expand Down
2 changes: 1 addition & 1 deletion trunk/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c
Original file line number Diff line number Diff line change
Expand Up @@ -913,7 +913,7 @@ static void l2t_put(struct cxgbi_sock *csk)
struct t3cdev *t3dev = (struct t3cdev *)csk->cdev->lldev;

if (csk->l2t) {
l2t_release(L2DATA(t3dev), csk->l2t);
l2t_release(t3dev, csk->l2t);
csk->l2t = NULL;
cxgbi_sock_put(csk);
}
Expand Down

0 comments on commit 895e042

Please sign in to comment.