Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

timens: Remove dependency on the vDSO

Previously, missing time namespace support in the vDSO meant that time
namespaces needed to be disabled globally. This was expressed in a hard
dependency on the generic vDSO library. This also meant that architectures
without any vDSO or only a stub vDSO could not enable time namespaces.
Now that all architectures using a real vDSO are using the generic library,
that dependency is not necessary anymore.

Remove the dependency and let all architectures enable time namespaces.

Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@kernel.org>
Link: https://patch.msgid.link/20260326-vdso-timens-decoupling-v2-2-c82693a7775f@linutronix.de

authored by

Thomas Weißschuh and committed by
Thomas Gleixner
1b6c8928 5dc9cf83

+54 -18
+16 -12
include/linux/time_namespace.h
··· 25 25 struct ucounts *ucounts; 26 26 struct ns_common ns; 27 27 struct timens_offsets offsets; 28 + #ifdef CONFIG_TIME_NS_VDSO 28 29 struct page *vvar_page; 30 + #endif 29 31 /* If set prevents changing offsets after any task joined namespace. */ 30 32 bool frozen_offsets; 31 33 } __randomize_layout; ··· 40 38 return container_of(ns, struct time_namespace, ns); 41 39 } 42 40 void __init time_ns_init(void); 43 - extern void timens_commit(struct task_struct *tsk, struct time_namespace *ns); 44 41 45 42 static inline struct time_namespace *get_time_ns(struct time_namespace *ns) 46 43 { ··· 52 51 struct time_namespace *old_ns); 53 52 void free_time_ns(struct time_namespace *ns); 54 53 void timens_on_fork(struct nsproxy *nsproxy, struct task_struct *tsk); 55 - struct page *find_timens_vvar_page(struct vm_area_struct *vma); 56 54 57 55 static inline void put_time_ns(struct time_namespace *ns) 58 56 { ··· 115 115 { 116 116 } 117 117 118 - static inline void timens_commit(struct task_struct *tsk, 119 - struct time_namespace *ns) 120 - { 121 - } 122 - 123 118 static inline struct time_namespace *get_time_ns(struct time_namespace *ns) 124 119 { 125 120 return NULL; ··· 141 146 return; 142 147 } 143 148 144 - static inline struct page *find_timens_vvar_page(struct vm_area_struct *vma) 145 - { 146 - return NULL; 147 - } 148 - 149 149 static inline void timens_add_monotonic(struct timespec64 *ts) { } 150 150 static inline void timens_add_boottime(struct timespec64 *ts) { } 151 151 ··· 156 166 return tim; 157 167 } 158 168 #endif 169 + 170 + #ifdef CONFIG_TIME_NS_VDSO 171 + extern void timens_commit(struct task_struct *tsk, struct time_namespace *ns); 172 + struct page *find_timens_vvar_page(struct vm_area_struct *vma); 173 + #else /* !CONFIG_TIME_NS_VDSO */ 174 + static inline void timens_commit(struct task_struct *tsk, struct time_namespace *ns) 175 + { 176 + } 177 + 178 + static inline struct page *find_timens_vvar_page(struct vm_area_struct *vma) 179 + { 180 + return NULL; 181 + } 182 + #endif /* CONFIG_TIME_NS_VDSO */ 159 183 160 184 #endif /* _LINUX_TIMENS_H */
+3 -1
init/Kconfig
··· 1386 1386 1387 1387 config TIME_NS 1388 1388 bool "TIME namespace" 1389 - depends on GENERIC_GETTIMEOFDAY 1390 1389 default y 1391 1390 help 1392 1391 In this namespace boottime and monotonic clocks can be set. 1393 1392 The time will keep going with the same pace. 1393 + 1394 + config TIME_NS_VDSO 1395 + def_bool TIME_NS && GENERIC_GETTIMEOFDAY 1394 1396 1395 1397 config IPC_NS 1396 1398 bool "IPC namespace"
+2 -1
kernel/time/Makefile
··· 29 29 obj-$(CONFIG_GENERIC_GETTIMEOFDAY) += vsyscall.o 30 30 obj-$(CONFIG_DEBUG_FS) += timekeeping_debug.o 31 31 obj-$(CONFIG_TEST_UDELAY) += test_udelay.o 32 - obj-$(CONFIG_TIME_NS) += namespace.o namespace_vdso.o 32 + obj-$(CONFIG_TIME_NS) += namespace.o 33 + obj-$(CONFIG_TIME_NS_VDSO) += namespace_vdso.o 33 34 obj-$(CONFIG_TEST_CLOCKSOURCE_WATCHDOG) += clocksource-wdtest.o 34 35 obj-$(CONFIG_TIME_KUNIT_TEST) += time_test.o
+4 -4
kernel/time/namespace.c
··· 93 93 if (!ns) 94 94 goto fail_dec; 95 95 96 - ns->vvar_page = alloc_page(GFP_KERNEL_ACCOUNT | __GFP_ZERO); 97 - if (!ns->vvar_page) 96 + err = timens_vdso_alloc_vvar_page(ns); 97 + if (err) 98 98 goto fail_free; 99 99 100 100 err = ns_common_init(ns); ··· 109 109 return ns; 110 110 111 111 fail_free_page: 112 - __free_page(ns->vvar_page); 112 + timens_vdso_free_vvar_page(ns); 113 113 fail_free: 114 114 kfree(ns); 115 115 fail_dec: ··· 146 146 dec_time_namespaces(ns->ucounts); 147 147 put_user_ns(ns->user_ns); 148 148 ns_common_free(ns); 149 - __free_page(ns->vvar_page); 149 + timens_vdso_free_vvar_page(ns); 150 150 /* Concurrent nstree traversal depends on a grace period. */ 151 151 kfree_rcu(ns, ns.ns_rcu); 152 152 }
+15
kernel/time/namespace_internal.h
··· 4 4 5 5 #include <linux/mutex.h> 6 6 7 + struct time_namespace; 8 + 7 9 /* 8 10 * Protects possibly multiple offsets writers racing each other 9 11 * and tasks entering the namespace. 10 12 */ 11 13 extern struct mutex timens_offset_lock; 14 + 15 + #ifdef CONFIG_TIME_NS_VDSO 16 + int timens_vdso_alloc_vvar_page(struct time_namespace *ns); 17 + void timens_vdso_free_vvar_page(struct time_namespace *ns); 18 + #else /* !CONFIG_TIME_NS_VDSO */ 19 + static inline int timens_vdso_alloc_vvar_page(struct time_namespace *ns) 20 + { 21 + return 0; 22 + } 23 + static inline void timens_vdso_free_vvar_page(struct time_namespace *ns) 24 + { 25 + } 26 + #endif /* CONFIG_TIME_NS_VDSO */ 12 27 13 28 #endif /* _TIME_NAMESPACE_INTERNAL_H */
+14
kernel/time/namespace_vdso.c
··· 144 144 timens_set_vvar_page(tsk, ns); 145 145 vdso_join_timens(tsk, ns); 146 146 } 147 + 148 + int timens_vdso_alloc_vvar_page(struct time_namespace *ns) 149 + { 150 + ns->vvar_page = alloc_page(GFP_KERNEL_ACCOUNT | __GFP_ZERO); 151 + if (!ns->vvar_page) 152 + return -ENOMEM; 153 + 154 + return 0; 155 + } 156 + 157 + void timens_vdso_free_vvar_page(struct time_namespace *ns) 158 + { 159 + __free_page(ns->vvar_page); 160 + }