@@ -6177,8 +6177,12 @@ static void __busy_poll_stop(struct napi_struct *napi, bool skip_schedule)
6177
6177
clear_bit (NAPI_STATE_SCHED , & napi -> state );
6178
6178
}
6179
6179
6180
- static void busy_poll_stop (struct napi_struct * napi , void * have_poll_lock , bool prefer_busy_poll ,
6181
- u16 budget )
6180
+ enum {
6181
+ NAPI_F_PREFER_BUSY_POLL = 1 ,
6182
+ };
6183
+
6184
+ static void busy_poll_stop (struct napi_struct * napi , void * have_poll_lock ,
6185
+ unsigned flags , u16 budget )
6182
6186
{
6183
6187
bool skip_schedule = false;
6184
6188
unsigned long timeout ;
@@ -6198,7 +6202,7 @@ static void busy_poll_stop(struct napi_struct *napi, void *have_poll_lock, bool
6198
6202
6199
6203
local_bh_disable ();
6200
6204
6201
- if (prefer_busy_poll ) {
6205
+ if (flags & NAPI_F_PREFER_BUSY_POLL ) {
6202
6206
napi -> defer_hard_irqs_count = READ_ONCE (napi -> dev -> napi_defer_hard_irqs );
6203
6207
timeout = READ_ONCE (napi -> dev -> gro_flush_timeout );
6204
6208
if (napi -> defer_hard_irqs_count && timeout ) {
@@ -6222,23 +6226,23 @@ static void busy_poll_stop(struct napi_struct *napi, void *have_poll_lock, bool
6222
6226
local_bh_enable ();
6223
6227
}
6224
6228
6225
- void napi_busy_loop (unsigned int napi_id ,
6226
- bool (* loop_end )(void * , unsigned long ),
6227
- void * loop_end_arg , bool prefer_busy_poll , u16 budget )
6229
+ static void __napi_busy_loop (unsigned int napi_id ,
6230
+ bool (* loop_end )(void * , unsigned long ),
6231
+ void * loop_end_arg , unsigned flags , u16 budget )
6228
6232
{
6229
6233
unsigned long start_time = loop_end ? busy_loop_current_time () : 0 ;
6230
6234
int (* napi_poll )(struct napi_struct * napi , int budget );
6231
6235
void * have_poll_lock = NULL ;
6232
6236
struct napi_struct * napi ;
6233
6237
6238
+ WARN_ON_ONCE (!rcu_read_lock_held ());
6239
+
6234
6240
restart :
6235
6241
napi_poll = NULL ;
6236
6242
6237
- rcu_read_lock ();
6238
-
6239
6243
napi = napi_by_id (napi_id );
6240
6244
if (!napi )
6241
- goto out ;
6245
+ return ;
6242
6246
6243
6247
if (!IS_ENABLED (CONFIG_PREEMPT_RT ))
6244
6248
preempt_disable ();
@@ -6254,14 +6258,14 @@ void napi_busy_loop(unsigned int napi_id,
6254
6258
*/
6255
6259
if (val & (NAPIF_STATE_DISABLE | NAPIF_STATE_SCHED |
6256
6260
NAPIF_STATE_IN_BUSY_POLL )) {
6257
- if (prefer_busy_poll )
6261
+ if (flags & NAPI_F_PREFER_BUSY_POLL )
6258
6262
set_bit (NAPI_STATE_PREFER_BUSY_POLL , & napi -> state );
6259
6263
goto count ;
6260
6264
}
6261
6265
if (cmpxchg (& napi -> state , val ,
6262
6266
val | NAPIF_STATE_IN_BUSY_POLL |
6263
6267
NAPIF_STATE_SCHED ) != val ) {
6264
- if (prefer_busy_poll )
6268
+ if (flags & NAPI_F_PREFER_BUSY_POLL )
6265
6269
set_bit (NAPI_STATE_PREFER_BUSY_POLL , & napi -> state );
6266
6270
goto count ;
6267
6271
}
@@ -6282,22 +6286,32 @@ void napi_busy_loop(unsigned int napi_id,
6282
6286
6283
6287
if (unlikely (need_resched ())) {
6284
6288
if (napi_poll )
6285
- busy_poll_stop (napi , have_poll_lock , prefer_busy_poll , budget );
6289
+ busy_poll_stop (napi , have_poll_lock , flags , budget );
6286
6290
if (!IS_ENABLED (CONFIG_PREEMPT_RT ))
6287
6291
preempt_enable ();
6288
6292
rcu_read_unlock ();
6289
6293
cond_resched ();
6294
+ rcu_read_lock ();
6290
6295
if (loop_end (loop_end_arg , start_time ))
6291
6296
return ;
6292
6297
goto restart ;
6293
6298
}
6294
6299
cpu_relax ();
6295
6300
}
6296
6301
if (napi_poll )
6297
- busy_poll_stop (napi , have_poll_lock , prefer_busy_poll , budget );
6302
+ busy_poll_stop (napi , have_poll_lock , flags , budget );
6298
6303
if (!IS_ENABLED (CONFIG_PREEMPT_RT ))
6299
6304
preempt_enable ();
6300
- out :
6305
+ }
6306
+
6307
+ void napi_busy_loop (unsigned int napi_id ,
6308
+ bool (* loop_end )(void * , unsigned long ),
6309
+ void * loop_end_arg , bool prefer_busy_poll , u16 budget )
6310
+ {
6311
+ unsigned flags = prefer_busy_poll ? NAPI_F_PREFER_BUSY_POLL : 0 ;
6312
+
6313
+ rcu_read_lock ();
6314
+ __napi_busy_loop (napi_id , loop_end , loop_end_arg , flags , budget );
6301
6315
rcu_read_unlock ();
6302
6316
}
6303
6317
EXPORT_SYMBOL (napi_busy_loop );
0 commit comments