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