posix-timers.c (58e16d792a6a8c6b750f637a4649967fcac853dc) | posix-timers.c (ec8f954a40da8cd3d159713b608e901f0cd909a9) |
---|---|
1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * 2002-10-15 Posix Clocks & timers 4 * by George Anzinger george@mvista.com 5 * Copyright (C) 2002 2003 by MontaVista Software. 6 * 7 * 2004-06-01 Fix CLOCK_REALTIME clock/timer TIMER_ABSTIME bug. 8 * Copyright (C) 2004 Boris Hu --- 428 unchanged lines hidden (view full) --- 437 return NULL; 438 } 439 clear_siginfo(&tmr->sigq->info); 440 return tmr; 441} 442 443static void k_itimer_rcu_free(struct rcu_head *head) 444{ | 1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * 2002-10-15 Posix Clocks & timers 4 * by George Anzinger george@mvista.com 5 * Copyright (C) 2002 2003 by MontaVista Software. 6 * 7 * 2004-06-01 Fix CLOCK_REALTIME clock/timer TIMER_ABSTIME bug. 8 * Copyright (C) 2004 Boris Hu --- 428 unchanged lines hidden (view full) --- 437 return NULL; 438 } 439 clear_siginfo(&tmr->sigq->info); 440 return tmr; 441} 442 443static void k_itimer_rcu_free(struct rcu_head *head) 444{ |
445 struct k_itimer *tmr = container_of(head, struct k_itimer, it.rcu); | 445 struct k_itimer *tmr = container_of(head, struct k_itimer, rcu); |
446 447 kmem_cache_free(posix_timers_cache, tmr); 448} 449 450#define IT_ID_SET 1 451#define IT_ID_NOT_SET 0 452static void release_posix_timer(struct k_itimer *tmr, int it_id_set) 453{ 454 if (it_id_set) { 455 unsigned long flags; 456 spin_lock_irqsave(&hash_lock, flags); 457 hlist_del_rcu(&tmr->t_hash); 458 spin_unlock_irqrestore(&hash_lock, flags); 459 } 460 put_pid(tmr->it_pid); 461 sigqueue_free(tmr->sigq); | 446 447 kmem_cache_free(posix_timers_cache, tmr); 448} 449 450#define IT_ID_SET 1 451#define IT_ID_NOT_SET 0 452static void release_posix_timer(struct k_itimer *tmr, int it_id_set) 453{ 454 if (it_id_set) { 455 unsigned long flags; 456 spin_lock_irqsave(&hash_lock, flags); 457 hlist_del_rcu(&tmr->t_hash); 458 spin_unlock_irqrestore(&hash_lock, flags); 459 } 460 put_pid(tmr->it_pid); 461 sigqueue_free(tmr->sigq); |
462 call_rcu(&tmr->it.rcu, k_itimer_rcu_free); | 462 call_rcu(&tmr->rcu, k_itimer_rcu_free); |
463} 464 465static int common_timer_create(struct k_itimer *new_timer) 466{ 467 hrtimer_init(&new_timer->it.real.timer, new_timer->it_clock, 0); 468 return 0; 469} 470 --- 329 unchanged lines hidden (view full) --- 800 hrtimer_start_expires(timer, HRTIMER_MODE_ABS); 801} 802 803static int common_hrtimer_try_to_cancel(struct k_itimer *timr) 804{ 805 return hrtimer_try_to_cancel(&timr->it.real.timer); 806} 807 | 463} 464 465static int common_timer_create(struct k_itimer *new_timer) 466{ 467 hrtimer_init(&new_timer->it.real.timer, new_timer->it_clock, 0); 468 return 0; 469} 470 --- 329 unchanged lines hidden (view full) --- 800 hrtimer_start_expires(timer, HRTIMER_MODE_ABS); 801} 802 803static int common_hrtimer_try_to_cancel(struct k_itimer *timr) 804{ 805 return hrtimer_try_to_cancel(&timr->it.real.timer); 806} 807 |
808static void common_timer_wait_running(struct k_itimer *timer) 809{ 810 hrtimer_cancel_wait_running(&timer->it.real.timer); 811} 812 813static struct k_itimer *timer_wait_running(struct k_itimer *timer, 814 unsigned long *flags) 815{ 816 const struct k_clock *kc = READ_ONCE(timer->kclock); 817 timer_t timer_id = READ_ONCE(timer->it_id); 818 819 /* Prevent kfree(timer) after dropping the lock */ 820 rcu_read_lock(); 821 unlock_timer(timer, *flags); 822 823 if (!WARN_ON_ONCE(!kc->timer_wait_running)) 824 kc->timer_wait_running(timer); 825 826 rcu_read_unlock(); 827 /* Relock the timer. It might be not longer hashed. */ 828 return lock_timer(timer_id, flags); 829} 830 |
|
808/* Set a POSIX.1b interval timer. */ 809int common_timer_set(struct k_itimer *timr, int flags, 810 struct itimerspec64 *new_setting, 811 struct itimerspec64 *old_setting) 812{ 813 const struct k_clock *kc = timr->kclock; 814 bool sigev_none; 815 ktime_t expires; --- 23 unchanged lines hidden (view full) --- 839 expires = timespec64_to_ktime(new_setting->it_value); 840 sigev_none = timr->it_sigev_notify == SIGEV_NONE; 841 842 kc->timer_arm(timr, expires, flags & TIMER_ABSTIME, sigev_none); 843 timr->it_active = !sigev_none; 844 return 0; 845} 846 | 831/* Set a POSIX.1b interval timer. */ 832int common_timer_set(struct k_itimer *timr, int flags, 833 struct itimerspec64 *new_setting, 834 struct itimerspec64 *old_setting) 835{ 836 const struct k_clock *kc = timr->kclock; 837 bool sigev_none; 838 ktime_t expires; --- 23 unchanged lines hidden (view full) --- 862 expires = timespec64_to_ktime(new_setting->it_value); 863 sigev_none = timr->it_sigev_notify == SIGEV_NONE; 864 865 kc->timer_arm(timr, expires, flags & TIMER_ABSTIME, sigev_none); 866 timr->it_active = !sigev_none; 867 return 0; 868} 869 |
847static int do_timer_settime(timer_t timer_id, int flags, | 870static int do_timer_settime(timer_t timer_id, int tmr_flags, |
848 struct itimerspec64 *new_spec64, 849 struct itimerspec64 *old_spec64) 850{ 851 const struct k_clock *kc; 852 struct k_itimer *timr; | 871 struct itimerspec64 *new_spec64, 872 struct itimerspec64 *old_spec64) 873{ 874 const struct k_clock *kc; 875 struct k_itimer *timr; |
853 unsigned long flag; | 876 unsigned long flags; |
854 int error = 0; 855 856 if (!timespec64_valid(&new_spec64->it_interval) || 857 !timespec64_valid(&new_spec64->it_value)) 858 return -EINVAL; 859 860 if (old_spec64) 861 memset(old_spec64, 0, sizeof(*old_spec64)); | 877 int error = 0; 878 879 if (!timespec64_valid(&new_spec64->it_interval) || 880 !timespec64_valid(&new_spec64->it_value)) 881 return -EINVAL; 882 883 if (old_spec64) 884 memset(old_spec64, 0, sizeof(*old_spec64)); |
885 886 timr = lock_timer(timer_id, &flags); |
|
862retry: | 887retry: |
863 timr = lock_timer(timer_id, &flag); | |
864 if (!timr) 865 return -EINVAL; 866 867 kc = timr->kclock; 868 if (WARN_ON_ONCE(!kc || !kc->timer_set)) 869 error = -EINVAL; 870 else | 888 if (!timr) 889 return -EINVAL; 890 891 kc = timr->kclock; 892 if (WARN_ON_ONCE(!kc || !kc->timer_set)) 893 error = -EINVAL; 894 else |
871 error = kc->timer_set(timr, flags, new_spec64, old_spec64); | 895 error = kc->timer_set(timr, tmr_flags, new_spec64, old_spec64); |
872 | 896 |
873 unlock_timer(timr, flag); | |
874 if (error == TIMER_RETRY) { | 897 if (error == TIMER_RETRY) { |
875 old_spec64 = NULL; // We already got the old time... | 898 // We already got the old time... 899 old_spec64 = NULL; 900 /* Unlocks and relocks the timer if it still exists */ 901 timr = timer_wait_running(timr, &flags); |
876 goto retry; 877 } | 902 goto retry; 903 } |
904 unlock_timer(timr, flags); |
|
878 879 return error; 880} 881 882/* Set a POSIX.1b interval timer */ 883SYSCALL_DEFINE4(timer_settime, timer_t, timer_id, int, flags, 884 const struct __kernel_itimerspec __user *, new_setting, 885 struct __kernel_itimerspec __user *, old_setting) --- 60 unchanged lines hidden (view full) --- 946} 947 948/* Delete a POSIX.1b interval timer. */ 949SYSCALL_DEFINE1(timer_delete, timer_t, timer_id) 950{ 951 struct k_itimer *timer; 952 unsigned long flags; 953 | 905 906 return error; 907} 908 909/* Set a POSIX.1b interval timer */ 910SYSCALL_DEFINE4(timer_settime, timer_t, timer_id, int, flags, 911 const struct __kernel_itimerspec __user *, new_setting, 912 struct __kernel_itimerspec __user *, old_setting) --- 60 unchanged lines hidden (view full) --- 973} 974 975/* Delete a POSIX.1b interval timer. */ 976SYSCALL_DEFINE1(timer_delete, timer_t, timer_id) 977{ 978 struct k_itimer *timer; 979 unsigned long flags; 980 |
954retry_delete: | |
955 timer = lock_timer(timer_id, &flags); | 981 timer = lock_timer(timer_id, &flags); |
982 983retry_delete: |
|
956 if (!timer) 957 return -EINVAL; 958 | 984 if (!timer) 985 return -EINVAL; 986 |
959 if (timer_delete_hook(timer) == TIMER_RETRY) { 960 unlock_timer(timer, flags); | 987 if (unlikely(timer_delete_hook(timer) == TIMER_RETRY)) { 988 /* Unlocks and relocks the timer if it still exists */ 989 timer = timer_wait_running(timer, &flags); |
961 goto retry_delete; 962 } 963 964 spin_lock(¤t->sighand->siglock); 965 list_del(&timer->list); 966 spin_unlock(¤t->sighand->siglock); 967 /* 968 * This keeps any tasks waiting on the spin lock from thinking --- 264 unchanged lines hidden (view full) --- 1233 .timer_create = common_timer_create, 1234 .timer_set = common_timer_set, 1235 .timer_get = common_timer_get, 1236 .timer_del = common_timer_del, 1237 .timer_rearm = common_hrtimer_rearm, 1238 .timer_forward = common_hrtimer_forward, 1239 .timer_remaining = common_hrtimer_remaining, 1240 .timer_try_to_cancel = common_hrtimer_try_to_cancel, | 990 goto retry_delete; 991 } 992 993 spin_lock(¤t->sighand->siglock); 994 list_del(&timer->list); 995 spin_unlock(¤t->sighand->siglock); 996 /* 997 * This keeps any tasks waiting on the spin lock from thinking --- 264 unchanged lines hidden (view full) --- 1262 .timer_create = common_timer_create, 1263 .timer_set = common_timer_set, 1264 .timer_get = common_timer_get, 1265 .timer_del = common_timer_del, 1266 .timer_rearm = common_hrtimer_rearm, 1267 .timer_forward = common_hrtimer_forward, 1268 .timer_remaining = common_hrtimer_remaining, 1269 .timer_try_to_cancel = common_hrtimer_try_to_cancel, |
1270 .timer_wait_running = common_timer_wait_running, |
|
1241 .timer_arm = common_hrtimer_arm, 1242}; 1243 1244static const struct k_clock clock_monotonic = { 1245 .clock_getres = posix_get_hrtimer_res, 1246 .clock_get = posix_ktime_get_ts, 1247 .nsleep = common_nsleep, 1248 .timer_create = common_timer_create, 1249 .timer_set = common_timer_set, 1250 .timer_get = common_timer_get, 1251 .timer_del = common_timer_del, 1252 .timer_rearm = common_hrtimer_rearm, 1253 .timer_forward = common_hrtimer_forward, 1254 .timer_remaining = common_hrtimer_remaining, 1255 .timer_try_to_cancel = common_hrtimer_try_to_cancel, | 1271 .timer_arm = common_hrtimer_arm, 1272}; 1273 1274static const struct k_clock clock_monotonic = { 1275 .clock_getres = posix_get_hrtimer_res, 1276 .clock_get = posix_ktime_get_ts, 1277 .nsleep = common_nsleep, 1278 .timer_create = common_timer_create, 1279 .timer_set = common_timer_set, 1280 .timer_get = common_timer_get, 1281 .timer_del = common_timer_del, 1282 .timer_rearm = common_hrtimer_rearm, 1283 .timer_forward = common_hrtimer_forward, 1284 .timer_remaining = common_hrtimer_remaining, 1285 .timer_try_to_cancel = common_hrtimer_try_to_cancel, |
1286 .timer_wait_running = common_timer_wait_running, |
|
1256 .timer_arm = common_hrtimer_arm, 1257}; 1258 1259static const struct k_clock clock_monotonic_raw = { 1260 .clock_getres = posix_get_hrtimer_res, 1261 .clock_get = posix_get_monotonic_raw, 1262}; 1263 --- 14 unchanged lines hidden (view full) --- 1278 .timer_create = common_timer_create, 1279 .timer_set = common_timer_set, 1280 .timer_get = common_timer_get, 1281 .timer_del = common_timer_del, 1282 .timer_rearm = common_hrtimer_rearm, 1283 .timer_forward = common_hrtimer_forward, 1284 .timer_remaining = common_hrtimer_remaining, 1285 .timer_try_to_cancel = common_hrtimer_try_to_cancel, | 1287 .timer_arm = common_hrtimer_arm, 1288}; 1289 1290static const struct k_clock clock_monotonic_raw = { 1291 .clock_getres = posix_get_hrtimer_res, 1292 .clock_get = posix_get_monotonic_raw, 1293}; 1294 --- 14 unchanged lines hidden (view full) --- 1309 .timer_create = common_timer_create, 1310 .timer_set = common_timer_set, 1311 .timer_get = common_timer_get, 1312 .timer_del = common_timer_del, 1313 .timer_rearm = common_hrtimer_rearm, 1314 .timer_forward = common_hrtimer_forward, 1315 .timer_remaining = common_hrtimer_remaining, 1316 .timer_try_to_cancel = common_hrtimer_try_to_cancel, |
1317 .timer_wait_running = common_timer_wait_running, |
|
1286 .timer_arm = common_hrtimer_arm, 1287}; 1288 1289static const struct k_clock clock_boottime = { 1290 .clock_getres = posix_get_hrtimer_res, 1291 .clock_get = posix_get_boottime, 1292 .nsleep = common_nsleep, 1293 .timer_create = common_timer_create, 1294 .timer_set = common_timer_set, 1295 .timer_get = common_timer_get, 1296 .timer_del = common_timer_del, 1297 .timer_rearm = common_hrtimer_rearm, 1298 .timer_forward = common_hrtimer_forward, 1299 .timer_remaining = common_hrtimer_remaining, 1300 .timer_try_to_cancel = common_hrtimer_try_to_cancel, | 1318 .timer_arm = common_hrtimer_arm, 1319}; 1320 1321static const struct k_clock clock_boottime = { 1322 .clock_getres = posix_get_hrtimer_res, 1323 .clock_get = posix_get_boottime, 1324 .nsleep = common_nsleep, 1325 .timer_create = common_timer_create, 1326 .timer_set = common_timer_set, 1327 .timer_get = common_timer_get, 1328 .timer_del = common_timer_del, 1329 .timer_rearm = common_hrtimer_rearm, 1330 .timer_forward = common_hrtimer_forward, 1331 .timer_remaining = common_hrtimer_remaining, 1332 .timer_try_to_cancel = common_hrtimer_try_to_cancel, |
1333 .timer_wait_running = common_timer_wait_running, |
|
1301 .timer_arm = common_hrtimer_arm, 1302}; 1303 1304static const struct k_clock * const posix_clocks[] = { 1305 [CLOCK_REALTIME] = &clock_realtime, 1306 [CLOCK_MONOTONIC] = &clock_monotonic, 1307 [CLOCK_PROCESS_CPUTIME_ID] = &clock_process, 1308 [CLOCK_THREAD_CPUTIME_ID] = &clock_thread, --- 23 unchanged lines hidden --- | 1334 .timer_arm = common_hrtimer_arm, 1335}; 1336 1337static const struct k_clock * const posix_clocks[] = { 1338 [CLOCK_REALTIME] = &clock_realtime, 1339 [CLOCK_MONOTONIC] = &clock_monotonic, 1340 [CLOCK_PROCESS_CPUTIME_ID] = &clock_process, 1341 [CLOCK_THREAD_CPUTIME_ID] = &clock_thread, --- 23 unchanged lines hidden --- |