aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/cisco/enic/vnic_rq.h
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/cisco/enic/vnic_rq.h')
-rw-r--r--drivers/net/ethernet/cisco/enic/vnic_rq.h91
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
79enum enic_poll_state {
80 ENIC_POLL_STATE_IDLE,
81 ENIC_POLL_STATE_NAPI,
82 ENIC_POLL_STATE_POLL
83};
84
78struct vnic_rq { 85struct 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
216static inline void enic_busy_poll_init_lock(struct vnic_rq *rq) 211static 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
222static inline bool enic_poll_lock_napi(struct vnic_rq *rq) 216static 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
239static inline bool enic_poll_unlock_napi(struct vnic_rq *rq) 224static 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
254static inline bool enic_poll_lock_poll(struct vnic_rq *rq) 232static 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
270static inline bool enic_poll_unlock_poll(struct vnic_rq *rq)
271{
272 bool rc = false;
273 240
274 spin_lock_bh(&rq->bpoll_lock); 241static 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
284static inline bool enic_poll_busy_polling(struct vnic_rq *rq) 247static 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
301static inline bool enic_poll_unlock_napi(struct vnic_rq *rq) 263static 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}