diff options
Diffstat (limited to 'net/core/netpoll.c')
-rw-r--r-- | net/core/netpoll.c | 10 |
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 | */ |
143 | static int poll_one_napi(struct napi_struct *napi, int budget) | 143 | static 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 | ||
167 | out: | ||
162 | return budget - work; | 168 | return budget - work; |
163 | } | 169 | } |
164 | 170 | ||