@@ -1079,11 +1079,20 @@ const struct bpf_func_proto bpf_snprintf_proto = {
10791079 .arg5_type = ARG_CONST_SIZE_OR_ZERO ,
10801080};
10811081
1082+ struct bpf_async_cb {
1083+ struct bpf_map * map ;
1084+ struct bpf_prog * prog ;
1085+ void __rcu * callback_fn ;
1086+ void * value ;
1087+ struct rcu_head rcu ;
1088+ u64 flags ;
1089+ };
1090+
10821091/* BPF map elements can contain 'struct bpf_timer'.
10831092 * Such map owns all of its BPF timers.
10841093 * 'struct bpf_timer' is allocated as part of map element allocation
10851094 * and it's zero initialized.
1086- * That space is used to keep 'struct bpf_timer_kern '.
1095+ * That space is used to keep 'struct bpf_async_kern '.
10871096 * bpf_timer_init() allocates 'struct bpf_hrtimer', inits hrtimer, and
10881097 * remembers 'struct bpf_map *' pointer it's part of.
10891098 * bpf_timer_set_callback() increments prog refcnt and assign bpf callback_fn.
@@ -1096,16 +1105,12 @@ const struct bpf_func_proto bpf_snprintf_proto = {
10961105 * freeing the timers when inner map is replaced or deleted by user space.
10971106 */
10981107struct bpf_hrtimer {
1108+ struct bpf_async_cb cb ;
10991109 struct hrtimer timer ;
1100- struct bpf_map * map ;
1101- struct bpf_prog * prog ;
1102- void __rcu * callback_fn ;
1103- void * value ;
1104- struct rcu_head rcu ;
11051110};
11061111
11071112/* the actual struct hidden inside uapi struct bpf_timer */
1108- struct bpf_timer_kern {
1113+ struct bpf_async_kern {
11091114 struct bpf_hrtimer * timer ;
11101115 /* bpf_spin_lock is used here instead of spinlock_t to make
11111116 * sure that it always fits into space reserved by struct bpf_timer
@@ -1119,14 +1124,14 @@ static DEFINE_PER_CPU(struct bpf_hrtimer *, hrtimer_running);
11191124static enum hrtimer_restart bpf_timer_cb (struct hrtimer * hrtimer )
11201125{
11211126 struct bpf_hrtimer * t = container_of (hrtimer , struct bpf_hrtimer , timer );
1122- struct bpf_map * map = t -> map ;
1123- void * value = t -> value ;
1127+ struct bpf_map * map = t -> cb . map ;
1128+ void * value = t -> cb . value ;
11241129 bpf_callback_t callback_fn ;
11251130 void * key ;
11261131 u32 idx ;
11271132
11281133 BTF_TYPE_EMIT (struct bpf_timer );
1129- callback_fn = rcu_dereference_check (t -> callback_fn , rcu_read_lock_bh_held ());
1134+ callback_fn = rcu_dereference_check (t -> cb . callback_fn , rcu_read_lock_bh_held ());
11301135 if (!callback_fn )
11311136 goto out ;
11321137
@@ -1155,16 +1160,16 @@ static enum hrtimer_restart bpf_timer_cb(struct hrtimer *hrtimer)
11551160 return HRTIMER_NORESTART ;
11561161}
11571162
1158- BPF_CALL_3 (bpf_timer_init , struct bpf_timer_kern * , timer , struct bpf_map * , map ,
1163+ BPF_CALL_3 (bpf_timer_init , struct bpf_async_kern * , timer , struct bpf_map * , map ,
11591164 u64 , flags )
11601165{
11611166 clockid_t clockid = flags & (MAX_CLOCKS - 1 );
11621167 struct bpf_hrtimer * t ;
11631168 int ret = 0 ;
11641169
11651170 BUILD_BUG_ON (MAX_CLOCKS != 16 );
1166- BUILD_BUG_ON (sizeof (struct bpf_timer_kern ) > sizeof (struct bpf_timer ));
1167- BUILD_BUG_ON (__alignof__(struct bpf_timer_kern ) != __alignof__(struct bpf_timer ));
1171+ BUILD_BUG_ON (sizeof (struct bpf_async_kern ) > sizeof (struct bpf_timer ));
1172+ BUILD_BUG_ON (__alignof__(struct bpf_async_kern ) != __alignof__(struct bpf_timer ));
11681173
11691174 if (in_nmi ())
11701175 return - EOPNOTSUPP ;
@@ -1187,10 +1192,10 @@ BPF_CALL_3(bpf_timer_init, struct bpf_timer_kern *, timer, struct bpf_map *, map
11871192 ret = - ENOMEM ;
11881193 goto out ;
11891194 }
1190- t -> value = (void * )timer - map -> record -> timer_off ;
1191- t -> map = map ;
1192- t -> prog = NULL ;
1193- rcu_assign_pointer (t -> callback_fn , NULL );
1195+ t -> cb . value = (void * )timer - map -> record -> timer_off ;
1196+ t -> cb . map = map ;
1197+ t -> cb . prog = NULL ;
1198+ rcu_assign_pointer (t -> cb . callback_fn , NULL );
11941199 hrtimer_init (& t -> timer , clockid , HRTIMER_MODE_REL_SOFT );
11951200 t -> timer .function = bpf_timer_cb ;
11961201 WRITE_ONCE (timer -> timer , t );
@@ -1222,7 +1227,7 @@ static const struct bpf_func_proto bpf_timer_init_proto = {
12221227 .arg3_type = ARG_ANYTHING ,
12231228};
12241229
1225- BPF_CALL_3 (bpf_timer_set_callback , struct bpf_timer_kern * , timer , void * , callback_fn ,
1230+ BPF_CALL_3 (bpf_timer_set_callback , struct bpf_async_kern * , timer , void * , callback_fn ,
12261231 struct bpf_prog_aux * , aux )
12271232{
12281233 struct bpf_prog * prev , * prog = aux -> prog ;
@@ -1237,7 +1242,7 @@ BPF_CALL_3(bpf_timer_set_callback, struct bpf_timer_kern *, timer, void *, callb
12371242 ret = - EINVAL ;
12381243 goto out ;
12391244 }
1240- if (!atomic64_read (& t -> map -> usercnt )) {
1245+ if (!atomic64_read (& t -> cb . map -> usercnt )) {
12411246 /* maps with timers must be either held by user space
12421247 * or pinned in bpffs. Otherwise timer might still be
12431248 * running even when bpf prog is detached and user space
@@ -1246,7 +1251,7 @@ BPF_CALL_3(bpf_timer_set_callback, struct bpf_timer_kern *, timer, void *, callb
12461251 ret = - EPERM ;
12471252 goto out ;
12481253 }
1249- prev = t -> prog ;
1254+ prev = t -> cb . prog ;
12501255 if (prev != prog ) {
12511256 /* Bump prog refcnt once. Every bpf_timer_set_callback()
12521257 * can pick different callback_fn-s within the same prog.
@@ -1259,9 +1264,9 @@ BPF_CALL_3(bpf_timer_set_callback, struct bpf_timer_kern *, timer, void *, callb
12591264 if (prev )
12601265 /* Drop prev prog refcnt when swapping with new prog */
12611266 bpf_prog_put (prev );
1262- t -> prog = prog ;
1267+ t -> cb . prog = prog ;
12631268 }
1264- rcu_assign_pointer (t -> callback_fn , callback_fn );
1269+ rcu_assign_pointer (t -> cb . callback_fn , callback_fn );
12651270out :
12661271 __bpf_spin_unlock_irqrestore (& timer -> lock );
12671272 return ret ;
@@ -1275,7 +1280,7 @@ static const struct bpf_func_proto bpf_timer_set_callback_proto = {
12751280 .arg2_type = ARG_PTR_TO_FUNC ,
12761281};
12771282
1278- BPF_CALL_3 (bpf_timer_start , struct bpf_timer_kern * , timer , u64 , nsecs , u64 , flags )
1283+ BPF_CALL_3 (bpf_timer_start , struct bpf_async_kern * , timer , u64 , nsecs , u64 , flags )
12791284{
12801285 struct bpf_hrtimer * t ;
12811286 int ret = 0 ;
@@ -1287,7 +1292,7 @@ BPF_CALL_3(bpf_timer_start, struct bpf_timer_kern *, timer, u64, nsecs, u64, fla
12871292 return - EINVAL ;
12881293 __bpf_spin_lock_irqsave (& timer -> lock );
12891294 t = timer -> timer ;
1290- if (!t || !t -> prog ) {
1295+ if (!t || !t -> cb . prog ) {
12911296 ret = - EINVAL ;
12921297 goto out ;
12931298 }
@@ -1315,18 +1320,18 @@ static const struct bpf_func_proto bpf_timer_start_proto = {
13151320 .arg3_type = ARG_ANYTHING ,
13161321};
13171322
1318- static void drop_prog_refcnt (struct bpf_hrtimer * t )
1323+ static void drop_prog_refcnt (struct bpf_async_cb * async )
13191324{
1320- struct bpf_prog * prog = t -> prog ;
1325+ struct bpf_prog * prog = async -> prog ;
13211326
13221327 if (prog ) {
13231328 bpf_prog_put (prog );
1324- t -> prog = NULL ;
1325- rcu_assign_pointer (t -> callback_fn , NULL );
1329+ async -> prog = NULL ;
1330+ rcu_assign_pointer (async -> callback_fn , NULL );
13261331 }
13271332}
13281333
1329- BPF_CALL_1 (bpf_timer_cancel , struct bpf_timer_kern * , timer )
1334+ BPF_CALL_1 (bpf_timer_cancel , struct bpf_async_kern * , timer )
13301335{
13311336 struct bpf_hrtimer * t ;
13321337 int ret = 0 ;
@@ -1348,7 +1353,7 @@ BPF_CALL_1(bpf_timer_cancel, struct bpf_timer_kern *, timer)
13481353 ret = - EDEADLK ;
13491354 goto out ;
13501355 }
1351- drop_prog_refcnt (t );
1356+ drop_prog_refcnt (& t -> cb );
13521357out :
13531358 __bpf_spin_unlock_irqrestore (& timer -> lock );
13541359 /* Cancel the timer and wait for associated callback to finish
@@ -1371,7 +1376,7 @@ static const struct bpf_func_proto bpf_timer_cancel_proto = {
13711376 */
13721377void bpf_timer_cancel_and_free (void * val )
13731378{
1374- struct bpf_timer_kern * timer = val ;
1379+ struct bpf_async_kern * timer = val ;
13751380 struct bpf_hrtimer * t ;
13761381
13771382 /* Performance optimization: read timer->timer without lock first. */
@@ -1383,7 +1388,7 @@ void bpf_timer_cancel_and_free(void *val)
13831388 t = timer -> timer ;
13841389 if (!t )
13851390 goto out ;
1386- drop_prog_refcnt (t );
1391+ drop_prog_refcnt (& t -> cb );
13871392 /* The subsequent bpf_timer_start/cancel() helpers won't be able to use
13881393 * this timer, since it won't be initialized.
13891394 */
@@ -1410,7 +1415,7 @@ void bpf_timer_cancel_and_free(void *val)
14101415 */
14111416 if (this_cpu_read (hrtimer_running ) != t )
14121417 hrtimer_cancel (& t -> timer );
1413- kfree_rcu (t , rcu );
1418+ kfree_rcu (t , cb . rcu );
14141419}
14151420
14161421BPF_CALL_2 (bpf_kptr_xchg , void * , map_value , void * , ptr )
0 commit comments