aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/cxgb3/l2t.h
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/cxgb3/l2t.h')
-rw-r--r--drivers/net/cxgb3/l2t.h16
1 files changed, 12 insertions, 4 deletions
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