diff options
Diffstat (limited to 'drivers/net/ethernet/cisco/enic/vnic_rq.h')
-rw-r--r-- | drivers/net/ethernet/cisco/enic/vnic_rq.h | 91 |
1 files changed, 27 insertions, 64 deletions
diff --git a/drivers/net/ethernet/cisco/enic/vnic_rq.h b/drivers/net/ethernet/cisco/enic/vnic_rq.h index 8111d5202df2..b9c82f143d7e 100644 --- a/drivers/net/ethernet/cisco/enic/vnic_rq.h +++ b/drivers/net/ethernet/cisco/enic/vnic_rq.h | |||
@@ -21,6 +21,7 @@ | |||
21 | #define _VNIC_RQ_H_ | 21 | #define _VNIC_RQ_H_ |
22 | 22 | ||
23 | #include <linux/pci.h> | 23 | #include <linux/pci.h> |
24 | #include <linux/netdevice.h> | ||
24 | 25 | ||
25 | #include "vnic_dev.h" | 26 | #include "vnic_dev.h" |
26 | #include "vnic_cq.h" | 27 | #include "vnic_cq.h" |
@@ -75,6 +76,12 @@ struct vnic_rq_buf { | |||
75 | uint64_t wr_id; | 76 | uint64_t wr_id; |
76 | }; | 77 | }; |
77 | 78 | ||
79 | enum enic_poll_state { | ||
80 | ENIC_POLL_STATE_IDLE, | ||
81 | ENIC_POLL_STATE_NAPI, | ||
82 | ENIC_POLL_STATE_POLL | ||
83 | }; | ||
84 | |||
78 | struct vnic_rq { | 85 | struct vnic_rq { |
79 | unsigned int index; | 86 | unsigned int index; |
80 | struct vnic_dev *vdev; | 87 | struct vnic_dev *vdev; |
@@ -86,19 +93,7 @@ struct vnic_rq { | |||
86 | void *os_buf_head; | 93 | void *os_buf_head; |
87 | unsigned int pkts_outstanding; | 94 | unsigned int pkts_outstanding; |
88 | #ifdef CONFIG_NET_RX_BUSY_POLL | 95 | #ifdef CONFIG_NET_RX_BUSY_POLL |
89 | #define ENIC_POLL_STATE_IDLE 0 | 96 | atomic_t bpoll_state; |
90 | #define ENIC_POLL_STATE_NAPI (1 << 0) /* NAPI owns this poll */ | ||
91 | #define ENIC_POLL_STATE_POLL (1 << 1) /* poll owns this poll */ | ||
92 | #define ENIC_POLL_STATE_NAPI_YIELD (1 << 2) /* NAPI yielded this poll */ | ||
93 | #define ENIC_POLL_STATE_POLL_YIELD (1 << 3) /* poll yielded this poll */ | ||
94 | #define ENIC_POLL_YIELD (ENIC_POLL_STATE_NAPI_YIELD | \ | ||
95 | ENIC_POLL_STATE_POLL_YIELD) | ||
96 | #define ENIC_POLL_LOCKED (ENIC_POLL_STATE_NAPI | \ | ||
97 | ENIC_POLL_STATE_POLL) | ||
98 | #define ENIC_POLL_USER_PEND (ENIC_POLL_STATE_POLL | \ | ||
99 | ENIC_POLL_STATE_POLL_YIELD) | ||
100 | unsigned int bpoll_state; | ||
101 | spinlock_t bpoll_lock; | ||
102 | #endif /* CONFIG_NET_RX_BUSY_POLL */ | 97 | #endif /* CONFIG_NET_RX_BUSY_POLL */ |
103 | }; | 98 | }; |
104 | 99 | ||
@@ -215,76 +210,43 @@ static inline int vnic_rq_fill(struct vnic_rq *rq, | |||
215 | #ifdef CONFIG_NET_RX_BUSY_POLL | 210 | #ifdef CONFIG_NET_RX_BUSY_POLL |
216 | static inline void enic_busy_poll_init_lock(struct vnic_rq *rq) | 211 | static inline void enic_busy_poll_init_lock(struct vnic_rq *rq) |
217 | { | 212 | { |
218 | spin_lock_init(&rq->bpoll_lock); | 213 | atomic_set(&rq->bpoll_state, ENIC_POLL_STATE_IDLE); |
219 | rq->bpoll_state = ENIC_POLL_STATE_IDLE; | ||
220 | } | 214 | } |
221 | 215 | ||
222 | static inline bool enic_poll_lock_napi(struct vnic_rq *rq) | 216 | static inline bool enic_poll_lock_napi(struct vnic_rq *rq) |
223 | { | 217 | { |
224 | bool rc = true; | 218 | int rc = atomic_cmpxchg(&rq->bpoll_state, ENIC_POLL_STATE_IDLE, |
225 | 219 | ENIC_POLL_STATE_NAPI); | |
226 | spin_lock(&rq->bpoll_lock); | ||
227 | if (rq->bpoll_state & ENIC_POLL_LOCKED) { | ||
228 | WARN_ON(rq->bpoll_state & ENIC_POLL_STATE_NAPI); | ||
229 | rq->bpoll_state |= ENIC_POLL_STATE_NAPI_YIELD; | ||
230 | rc = false; | ||
231 | } else { | ||
232 | rq->bpoll_state = ENIC_POLL_STATE_NAPI; | ||
233 | } | ||
234 | spin_unlock(&rq->bpoll_lock); | ||
235 | 220 | ||
236 | return rc; | 221 | return (rc == ENIC_POLL_STATE_IDLE); |
237 | } | 222 | } |
238 | 223 | ||
239 | static inline bool enic_poll_unlock_napi(struct vnic_rq *rq) | 224 | static inline void enic_poll_unlock_napi(struct vnic_rq *rq, |
225 | struct napi_struct *napi) | ||
240 | { | 226 | { |
241 | bool rc = false; | 227 | WARN_ON(atomic_read(&rq->bpoll_state) != ENIC_POLL_STATE_NAPI); |
242 | 228 | napi_gro_flush(napi, false); | |
243 | spin_lock(&rq->bpoll_lock); | 229 | atomic_set(&rq->bpoll_state, ENIC_POLL_STATE_IDLE); |
244 | WARN_ON(rq->bpoll_state & | ||
245 | (ENIC_POLL_STATE_POLL | ENIC_POLL_STATE_NAPI_YIELD)); | ||
246 | if (rq->bpoll_state & ENIC_POLL_STATE_POLL_YIELD) | ||
247 | rc = true; | ||
248 | rq->bpoll_state = ENIC_POLL_STATE_IDLE; | ||
249 | spin_unlock(&rq->bpoll_lock); | ||
250 | |||
251 | return rc; | ||
252 | } | 230 | } |
253 | 231 | ||
254 | static inline bool enic_poll_lock_poll(struct vnic_rq *rq) | 232 | static inline bool enic_poll_lock_poll(struct vnic_rq *rq) |
255 | { | 233 | { |
256 | bool rc = true; | 234 | int rc = atomic_cmpxchg(&rq->bpoll_state, ENIC_POLL_STATE_IDLE, |
257 | 235 | ENIC_POLL_STATE_POLL); | |
258 | spin_lock_bh(&rq->bpoll_lock); | ||
259 | if (rq->bpoll_state & ENIC_POLL_LOCKED) { | ||
260 | rq->bpoll_state |= ENIC_POLL_STATE_POLL_YIELD; | ||
261 | rc = false; | ||
262 | } else { | ||
263 | rq->bpoll_state |= ENIC_POLL_STATE_POLL; | ||
264 | } | ||
265 | spin_unlock_bh(&rq->bpoll_lock); | ||
266 | 236 | ||
267 | return rc; | 237 | return (rc == ENIC_POLL_STATE_IDLE); |
268 | } | 238 | } |
269 | 239 | ||
270 | static inline bool enic_poll_unlock_poll(struct vnic_rq *rq) | ||
271 | { | ||
272 | bool rc = false; | ||
273 | 240 | ||
274 | spin_lock_bh(&rq->bpoll_lock); | 241 | static inline void enic_poll_unlock_poll(struct vnic_rq *rq) |
275 | WARN_ON(rq->bpoll_state & ENIC_POLL_STATE_NAPI); | 242 | { |
276 | if (rq->bpoll_state & ENIC_POLL_STATE_POLL_YIELD) | 243 | WARN_ON(atomic_read(&rq->bpoll_state) != ENIC_POLL_STATE_POLL); |
277 | rc = true; | 244 | atomic_set(&rq->bpoll_state, ENIC_POLL_STATE_IDLE); |
278 | rq->bpoll_state = ENIC_POLL_STATE_IDLE; | ||
279 | spin_unlock_bh(&rq->bpoll_lock); | ||
280 | |||
281 | return rc; | ||
282 | } | 245 | } |
283 | 246 | ||
284 | static inline bool enic_poll_busy_polling(struct vnic_rq *rq) | 247 | static inline bool enic_poll_busy_polling(struct vnic_rq *rq) |
285 | { | 248 | { |
286 | WARN_ON(!(rq->bpoll_state & ENIC_POLL_LOCKED)); | 249 | return atomic_read(&rq->bpoll_state) & ENIC_POLL_STATE_POLL; |
287 | return rq->bpoll_state & ENIC_POLL_USER_PEND; | ||
288 | } | 250 | } |
289 | 251 | ||
290 | #else | 252 | #else |
@@ -298,7 +260,8 @@ static inline bool enic_poll_lock_napi(struct vnic_rq *rq) | |||
298 | return true; | 260 | return true; |
299 | } | 261 | } |
300 | 262 | ||
301 | static inline bool enic_poll_unlock_napi(struct vnic_rq *rq) | 263 | static inline bool enic_poll_unlock_napi(struct vnic_rq *rq, |
264 | struct napi_struct *napi) | ||
302 | { | 265 | { |
303 | return false; | 266 | return false; |
304 | } | 267 | } |