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(&current->sighand->siglock);
965 list_del(&timer->list);
966 spin_unlock(&current->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(&current->sighand->siglock);
994 list_del(&timer->list);
995 spin_unlock(&current->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 ---