aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/netpoll.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/core/netpoll.c')
-rw-r--r--net/core/netpoll.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index 6aa3db8dfc3b..8bdada242a7d 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -142,7 +142,7 @@ static void queue_process(struct work_struct *work)
142 */ 142 */
143static int poll_one_napi(struct napi_struct *napi, int budget) 143static int poll_one_napi(struct napi_struct *napi, int budget)
144{ 144{
145 int work; 145 int work = 0;
146 146
147 /* net_rx_action's ->poll() invocations and our's are 147 /* net_rx_action's ->poll() invocations and our's are
148 * synchronized by this test which is only made while 148 * synchronized by this test which is only made while
@@ -151,7 +151,12 @@ static int poll_one_napi(struct napi_struct *napi, int budget)
151 if (!test_bit(NAPI_STATE_SCHED, &napi->state)) 151 if (!test_bit(NAPI_STATE_SCHED, &napi->state))
152 return budget; 152 return budget;
153 153
154 set_bit(NAPI_STATE_NPSVC, &napi->state); 154 /* If we set this bit but see that it has already been set,
155 * that indicates that napi has been disabled and we need
156 * to abort this operation
157 */
158 if (test_and_set_bit(NAPI_STATE_NPSVC, &napi->state))
159 goto out;
155 160
156 work = napi->poll(napi, budget); 161 work = napi->poll(napi, budget);
157 WARN_ONCE(work > budget, "%pF exceeded budget in poll\n", napi->poll); 162 WARN_ONCE(work > budget, "%pF exceeded budget in poll\n", napi->poll);
@@ -159,6 +164,7 @@ static int poll_one_napi(struct napi_struct *napi, int budget)
159 164
160 clear_bit(NAPI_STATE_NPSVC, &napi->state); 165 clear_bit(NAPI_STATE_NPSVC, &napi->state);
161 166
167out:
162 return budget - work; 168 return budget - work;
163} 169}
164 170