diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/sched_clock.c | 3 | ||||
| -rw-r--r-- | kernel/user_namespace.c | 21 |
2 files changed, 19 insertions, 5 deletions
diff --git a/kernel/sched_clock.c b/kernel/sched_clock.c index f7602da84c40..7ec82c1c61c5 100644 --- a/kernel/sched_clock.c +++ b/kernel/sched_clock.c @@ -162,6 +162,8 @@ u64 sched_clock_cpu(int cpu) if (sched_clock_stable) return sched_clock(); + scd = cpu_sdc(cpu); + /* * Normally this is not called in NMI context - but if it is, * trying to do any locking here is totally lethal. @@ -172,7 +174,6 @@ u64 sched_clock_cpu(int cpu) if (unlikely(!sched_clock_running)) return 0ull; - scd = cpu_sdc(cpu); WARN_ON_ONCE(!irqs_disabled()); now = sched_clock(); diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c index 79084311ee57..076c7c8215b0 100644 --- a/kernel/user_namespace.c +++ b/kernel/user_namespace.c @@ -60,12 +60,25 @@ int create_user_ns(struct cred *new) return 0; } -void free_user_ns(struct kref *kref) +/* + * Deferred destructor for a user namespace. This is required because + * free_user_ns() may be called with uidhash_lock held, but we need to call + * back to free_uid() which will want to take the lock again. + */ +static void free_user_ns_work(struct work_struct *work) { - struct user_namespace *ns; - - ns = container_of(kref, struct user_namespace, kref); + struct user_namespace *ns = + container_of(work, struct user_namespace, destroyer); free_uid(ns->creator); kfree(ns); } + +void free_user_ns(struct kref *kref) +{ + struct user_namespace *ns = + container_of(kref, struct user_namespace, kref); + + INIT_WORK(&ns->destroyer, free_user_ns_work); + schedule_work(&ns->destroyer); +} EXPORT_SYMBOL(free_user_ns); |
