As usual, lots of singleton and doubleton patches all over the tree and
there's little I can say which isn't in the individual changelogs.
The lengthier patch series are
- "kdump: use generic functions to simplify crashkernel reservation in
arch", from Baoquan He. This is mainly cleanups and consolidation of
the "crashkernel=" kernel parameter handling.
- After much discussion, David Laight's "minmax: Relax type checks in
min() and max()" is here. Hopefully reduces some typecasting and the
use of min_t() and max_t().
- A group of patches from Oleg Nesterov which clean up and slightly fix
our handling of reads from /proc/PID/task/... and which remove
task_struct.therad_group.
-----BEGIN PGP SIGNATURE-----
iHUEABYIAB0WIQTTMBEPP41GrTpTJgfdBJ7gKXxAjgUCZUQP9wAKCRDdBJ7gKXxA
jmOAAQDh8sxagQYocoVsSm28ICqXFeaY9Co1jzBIDdNesAvYVwD/c2DHRqJHEiS4
63BNcG3+hM9nwGJHb5lyh5m79nBMRg0=
=On4u
-----END PGP SIGNATURE-----
Merge tag 'mm-nonmm-stable-2023-11-02-14-08' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
Pull non-MM updates from Andrew Morton:
"As usual, lots of singleton and doubleton patches all over the tree
and there's little I can say which isn't in the individual changelogs.
The lengthier patch series are
- 'kdump: use generic functions to simplify crashkernel reservation
in arch', from Baoquan He. This is mainly cleanups and
consolidation of the 'crashkernel=' kernel parameter handling
- After much discussion, David Laight's 'minmax: Relax type checks in
min() and max()' is here. Hopefully reduces some typecasting and
the use of min_t() and max_t()
- A group of patches from Oleg Nesterov which clean up and slightly
fix our handling of reads from /proc/PID/task/... and which remove
task_struct.thread_group"
* tag 'mm-nonmm-stable-2023-11-02-14-08' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm: (64 commits)
scripts/gdb/vmalloc: disable on no-MMU
scripts/gdb: fix usage of MOD_TEXT not defined when CONFIG_MODULES=n
.mailmap: add address mapping for Tomeu Vizoso
mailmap: update email address for Claudiu Beznea
tools/testing/selftests/mm/run_vmtests.sh: lower the ptrace permissions
.mailmap: map Benjamin Poirier's address
scripts/gdb: add lx_current support for riscv
ocfs2: fix a spelling typo in comment
proc: test ProtectionKey in proc-empty-vm test
proc: fix proc-empty-vm test with vsyscall
fs/proc/base.c: remove unneeded semicolon
do_io_accounting: use sig->stats_lock
do_io_accounting: use __for_each_thread()
ocfs2: replace BUG_ON() at ocfs2_num_free_extents() with ocfs2_error()
ocfs2: fix a typo in a comment
scripts/show_delta: add __main__ judgement before main code
treewide: mark stuff as __ro_after_init
fs: ocfs2: check status values
proc: test /proc/${pid}/statm
compiler.h: move __is_constexpr() to compiler.h
...
This commit is contained in:
commit
8f6f76a6a2
106 changed files with 920 additions and 1026 deletions
|
|
@ -110,7 +110,7 @@ config CRASH_DUMP
|
|||
For more details see Documentation/admin-guide/kdump/kdump.rst
|
||||
|
||||
For s390, this option also enables zfcpdump.
|
||||
See also <file:Documentation/s390/zfcpdump.rst>
|
||||
See also <file:Documentation/arch/s390/zfcpdump.rst>
|
||||
|
||||
config CRASH_HOTPLUG
|
||||
bool "Update the crash elfcorehdr on system configuration changes"
|
||||
|
|
|
|||
|
|
@ -87,8 +87,8 @@ static struct task_struct *prune_thread;
|
|||
* that makes a difference. Some.
|
||||
*/
|
||||
|
||||
static struct fsnotify_group *audit_tree_group;
|
||||
static struct kmem_cache *audit_tree_mark_cachep __read_mostly;
|
||||
static struct fsnotify_group *audit_tree_group __ro_after_init;
|
||||
static struct kmem_cache *audit_tree_mark_cachep __ro_after_init;
|
||||
|
||||
static struct audit_tree *alloc_tree(const char *s)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
*/
|
||||
|
||||
#include <linux/buildid.h>
|
||||
#include <linux/crash_core.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/utsname.h>
|
||||
#include <linux/vmalloc.h>
|
||||
|
|
@ -13,6 +12,9 @@
|
|||
#include <linux/kexec.h>
|
||||
#include <linux/memory.h>
|
||||
#include <linux/cpuhotplug.h>
|
||||
#include <linux/memblock.h>
|
||||
#include <linux/kexec.h>
|
||||
#include <linux/kmemleak.h>
|
||||
|
||||
#include <asm/page.h>
|
||||
#include <asm/sections.h>
|
||||
|
|
@ -33,6 +35,22 @@ u32 *vmcoreinfo_note;
|
|||
/* trusted vmcoreinfo, e.g. we can make a copy in the crash memory */
|
||||
static unsigned char *vmcoreinfo_data_safecopy;
|
||||
|
||||
/* Location of the reserved area for the crash kernel */
|
||||
struct resource crashk_res = {
|
||||
.name = "Crash kernel",
|
||||
.start = 0,
|
||||
.end = 0,
|
||||
.flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM,
|
||||
.desc = IORES_DESC_CRASH_KERNEL
|
||||
};
|
||||
struct resource crashk_low_res = {
|
||||
.name = "Crash kernel",
|
||||
.start = 0,
|
||||
.end = 0,
|
||||
.flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM,
|
||||
.desc = IORES_DESC_CRASH_KERNEL
|
||||
};
|
||||
|
||||
/*
|
||||
* parsing the "crashkernel" commandline
|
||||
*
|
||||
|
|
@ -248,11 +266,11 @@ static int __init __parse_crashkernel(char *cmdline,
|
|||
unsigned long long system_ram,
|
||||
unsigned long long *crash_size,
|
||||
unsigned long long *crash_base,
|
||||
const char *name,
|
||||
const char *suffix)
|
||||
{
|
||||
char *first_colon, *first_space;
|
||||
char *ck_cmdline;
|
||||
char *name = "crashkernel=";
|
||||
|
||||
BUG_ON(!crash_size || !crash_base);
|
||||
*crash_size = 0;
|
||||
|
|
@ -283,32 +301,53 @@ static int __init __parse_crashkernel(char *cmdline,
|
|||
/*
|
||||
* That function is the entry point for command line parsing and should be
|
||||
* called from the arch-specific code.
|
||||
*
|
||||
* If crashkernel=,high|low is supported on architecture, non-NULL values
|
||||
* should be passed to parameters 'low_size' and 'high'.
|
||||
*/
|
||||
int __init parse_crashkernel(char *cmdline,
|
||||
unsigned long long system_ram,
|
||||
unsigned long long *crash_size,
|
||||
unsigned long long *crash_base)
|
||||
unsigned long long *crash_base,
|
||||
unsigned long long *low_size,
|
||||
bool *high)
|
||||
{
|
||||
return __parse_crashkernel(cmdline, system_ram, crash_size, crash_base,
|
||||
"crashkernel=", NULL);
|
||||
}
|
||||
int ret;
|
||||
|
||||
int __init parse_crashkernel_high(char *cmdline,
|
||||
unsigned long long system_ram,
|
||||
unsigned long long *crash_size,
|
||||
unsigned long long *crash_base)
|
||||
{
|
||||
return __parse_crashkernel(cmdline, system_ram, crash_size, crash_base,
|
||||
"crashkernel=", suffix_tbl[SUFFIX_HIGH]);
|
||||
}
|
||||
/* crashkernel=X[@offset] */
|
||||
ret = __parse_crashkernel(cmdline, system_ram, crash_size,
|
||||
crash_base, NULL);
|
||||
#ifdef CONFIG_ARCH_HAS_GENERIC_CRASHKERNEL_RESERVATION
|
||||
/*
|
||||
* If non-NULL 'high' passed in and no normal crashkernel
|
||||
* setting detected, try parsing crashkernel=,high|low.
|
||||
*/
|
||||
if (high && ret == -ENOENT) {
|
||||
ret = __parse_crashkernel(cmdline, 0, crash_size,
|
||||
crash_base, suffix_tbl[SUFFIX_HIGH]);
|
||||
if (ret || !*crash_size)
|
||||
return -EINVAL;
|
||||
|
||||
int __init parse_crashkernel_low(char *cmdline,
|
||||
unsigned long long system_ram,
|
||||
unsigned long long *crash_size,
|
||||
unsigned long long *crash_base)
|
||||
{
|
||||
return __parse_crashkernel(cmdline, system_ram, crash_size, crash_base,
|
||||
"crashkernel=", suffix_tbl[SUFFIX_LOW]);
|
||||
/*
|
||||
* crashkernel=Y,low can be specified or not, but invalid value
|
||||
* is not allowed.
|
||||
*/
|
||||
ret = __parse_crashkernel(cmdline, 0, low_size,
|
||||
crash_base, suffix_tbl[SUFFIX_LOW]);
|
||||
if (ret == -ENOENT) {
|
||||
*low_size = DEFAULT_CRASH_KERNEL_LOW_SIZE;
|
||||
ret = 0;
|
||||
} else if (ret) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
*high = true;
|
||||
}
|
||||
#endif
|
||||
if (!*crash_size)
|
||||
ret = -EINVAL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -321,6 +360,109 @@ static int __init parse_crashkernel_dummy(char *arg)
|
|||
}
|
||||
early_param("crashkernel", parse_crashkernel_dummy);
|
||||
|
||||
#ifdef CONFIG_ARCH_HAS_GENERIC_CRASHKERNEL_RESERVATION
|
||||
static int __init reserve_crashkernel_low(unsigned long long low_size)
|
||||
{
|
||||
#ifdef CONFIG_64BIT
|
||||
unsigned long long low_base;
|
||||
|
||||
low_base = memblock_phys_alloc_range(low_size, CRASH_ALIGN, 0, CRASH_ADDR_LOW_MAX);
|
||||
if (!low_base) {
|
||||
pr_err("cannot allocate crashkernel low memory (size:0x%llx).\n", low_size);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
pr_info("crashkernel low memory reserved: 0x%08llx - 0x%08llx (%lld MB)\n",
|
||||
low_base, low_base + low_size, low_size >> 20);
|
||||
|
||||
crashk_low_res.start = low_base;
|
||||
crashk_low_res.end = low_base + low_size - 1;
|
||||
insert_resource(&iomem_resource, &crashk_low_res);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
void __init reserve_crashkernel_generic(char *cmdline,
|
||||
unsigned long long crash_size,
|
||||
unsigned long long crash_base,
|
||||
unsigned long long crash_low_size,
|
||||
bool high)
|
||||
{
|
||||
unsigned long long search_end = CRASH_ADDR_LOW_MAX, search_base = 0;
|
||||
bool fixed_base = false;
|
||||
|
||||
/* User specifies base address explicitly. */
|
||||
if (crash_base) {
|
||||
fixed_base = true;
|
||||
search_base = crash_base;
|
||||
search_end = crash_base + crash_size;
|
||||
} else if (high) {
|
||||
search_base = CRASH_ADDR_LOW_MAX;
|
||||
search_end = CRASH_ADDR_HIGH_MAX;
|
||||
}
|
||||
|
||||
retry:
|
||||
crash_base = memblock_phys_alloc_range(crash_size, CRASH_ALIGN,
|
||||
search_base, search_end);
|
||||
if (!crash_base) {
|
||||
/*
|
||||
* For crashkernel=size[KMG]@offset[KMG], print out failure
|
||||
* message if can't reserve the specified region.
|
||||
*/
|
||||
if (fixed_base) {
|
||||
pr_warn("crashkernel reservation failed - memory is in use.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* For crashkernel=size[KMG], if the first attempt was for
|
||||
* low memory, fall back to high memory, the minimum required
|
||||
* low memory will be reserved later.
|
||||
*/
|
||||
if (!high && search_end == CRASH_ADDR_LOW_MAX) {
|
||||
search_end = CRASH_ADDR_HIGH_MAX;
|
||||
search_base = CRASH_ADDR_LOW_MAX;
|
||||
crash_low_size = DEFAULT_CRASH_KERNEL_LOW_SIZE;
|
||||
goto retry;
|
||||
}
|
||||
|
||||
/*
|
||||
* For crashkernel=size[KMG],high, if the first attempt was
|
||||
* for high memory, fall back to low memory.
|
||||
*/
|
||||
if (high && search_end == CRASH_ADDR_HIGH_MAX) {
|
||||
search_end = CRASH_ADDR_LOW_MAX;
|
||||
search_base = 0;
|
||||
goto retry;
|
||||
}
|
||||
pr_warn("cannot allocate crashkernel (size:0x%llx)\n",
|
||||
crash_size);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((crash_base > CRASH_ADDR_LOW_MAX) &&
|
||||
crash_low_size && reserve_crashkernel_low(crash_low_size)) {
|
||||
memblock_phys_free(crash_base, crash_size);
|
||||
return;
|
||||
}
|
||||
|
||||
pr_info("crashkernel reserved: 0x%016llx - 0x%016llx (%lld MB)\n",
|
||||
crash_base, crash_base + crash_size, crash_size >> 20);
|
||||
|
||||
/*
|
||||
* The crashkernel memory will be removed from the kernel linear
|
||||
* map. Inform kmemleak so that it won't try to access it.
|
||||
*/
|
||||
kmemleak_ignore_phys(crash_base);
|
||||
if (crashk_low_res.end)
|
||||
kmemleak_ignore_phys(crashk_low_res.start);
|
||||
|
||||
crashk_res.start = crash_base;
|
||||
crashk_res.end = crash_base + crash_size - 1;
|
||||
insert_resource(&iomem_resource, &crashk_res);
|
||||
}
|
||||
#endif
|
||||
|
||||
int crash_prepare_elf64_headers(struct crash_mem *mem, int need_kernel_map,
|
||||
void **addr, unsigned long *sz)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -135,7 +135,6 @@ static void __unhash_process(struct task_struct *p, bool group_dead)
|
|||
list_del_init(&p->sibling);
|
||||
__this_cpu_dec(process_counts);
|
||||
}
|
||||
list_del_rcu(&p->thread_group);
|
||||
list_del_rcu(&p->thread_node);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2577,7 +2577,6 @@ __latent_entropy struct task_struct *copy_process(
|
|||
p->dirty_paused_when = 0;
|
||||
|
||||
p->pdeath_signal = 0;
|
||||
INIT_LIST_HEAD(&p->thread_group);
|
||||
p->task_works = NULL;
|
||||
clear_posix_cputimers_work(p);
|
||||
|
||||
|
|
@ -2705,8 +2704,6 @@ __latent_entropy struct task_struct *copy_process(
|
|||
atomic_inc(¤t->signal->live);
|
||||
refcount_inc(¤t->signal->sigcnt);
|
||||
task_join_group_stop(p);
|
||||
list_add_tail_rcu(&p->thread_group,
|
||||
&p->group_leader->thread_group);
|
||||
list_add_tail_rcu(&p->thread_node,
|
||||
&p->signal->thread_head);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ struct gcov_iterator {
|
|||
struct gcov_info *info;
|
||||
size_t size;
|
||||
loff_t pos;
|
||||
char buffer[];
|
||||
char buffer[] __counted_by(size);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1852,15 +1852,13 @@ out_thread:
|
|||
struct task_struct *t = new->thread;
|
||||
|
||||
new->thread = NULL;
|
||||
kthread_stop(t);
|
||||
put_task_struct(t);
|
||||
kthread_stop_put(t);
|
||||
}
|
||||
if (new->secondary && new->secondary->thread) {
|
||||
struct task_struct *t = new->secondary->thread;
|
||||
|
||||
new->secondary->thread = NULL;
|
||||
kthread_stop(t);
|
||||
put_task_struct(t);
|
||||
kthread_stop_put(t);
|
||||
}
|
||||
out_mput:
|
||||
module_put(desc->owner);
|
||||
|
|
@ -1971,12 +1969,9 @@ static struct irqaction *__free_irq(struct irq_desc *desc, void *dev_id)
|
|||
* the same bit to a newly requested action.
|
||||
*/
|
||||
if (action->thread) {
|
||||
kthread_stop(action->thread);
|
||||
put_task_struct(action->thread);
|
||||
if (action->secondary && action->secondary->thread) {
|
||||
kthread_stop(action->secondary->thread);
|
||||
put_task_struct(action->secondary->thread);
|
||||
}
|
||||
kthread_stop_put(action->thread);
|
||||
if (action->secondary && action->secondary->thread)
|
||||
kthread_stop_put(action->secondary->thread);
|
||||
}
|
||||
|
||||
/* Last action releases resources */
|
||||
|
|
|
|||
|
|
@ -52,23 +52,6 @@ atomic_t __kexec_lock = ATOMIC_INIT(0);
|
|||
/* Flag to indicate we are going to kexec a new kernel */
|
||||
bool kexec_in_progress = false;
|
||||
|
||||
|
||||
/* Location of the reserved area for the crash kernel */
|
||||
struct resource crashk_res = {
|
||||
.name = "Crash kernel",
|
||||
.start = 0,
|
||||
.end = 0,
|
||||
.flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM,
|
||||
.desc = IORES_DESC_CRASH_KERNEL
|
||||
};
|
||||
struct resource crashk_low_res = {
|
||||
.name = "Crash kernel",
|
||||
.start = 0,
|
||||
.end = 0,
|
||||
.flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM,
|
||||
.desc = IORES_DESC_CRASH_KERNEL
|
||||
};
|
||||
|
||||
int kexec_should_crash(struct task_struct *p)
|
||||
{
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -715,6 +715,24 @@ int kthread_stop(struct task_struct *k)
|
|||
}
|
||||
EXPORT_SYMBOL(kthread_stop);
|
||||
|
||||
/**
|
||||
* kthread_stop_put - stop a thread and put its task struct
|
||||
* @k: thread created by kthread_create().
|
||||
*
|
||||
* Stops a thread created by kthread_create() and put its task_struct.
|
||||
* Only use when holding an extra task struct reference obtained by
|
||||
* calling get_task_struct().
|
||||
*/
|
||||
int kthread_stop_put(struct task_struct *k)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = kthread_stop(k);
|
||||
put_task_struct(k);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(kthread_stop_put);
|
||||
|
||||
int kthreadd(void *unused)
|
||||
{
|
||||
struct task_struct *tsk = current;
|
||||
|
|
|
|||
|
|
@ -192,14 +192,15 @@ atomic_t panic_cpu = ATOMIC_INIT(PANIC_CPU_INVALID);
|
|||
*/
|
||||
void nmi_panic(struct pt_regs *regs, const char *msg)
|
||||
{
|
||||
int old_cpu, cpu;
|
||||
int old_cpu, this_cpu;
|
||||
|
||||
cpu = raw_smp_processor_id();
|
||||
old_cpu = atomic_cmpxchg(&panic_cpu, PANIC_CPU_INVALID, cpu);
|
||||
old_cpu = PANIC_CPU_INVALID;
|
||||
this_cpu = raw_smp_processor_id();
|
||||
|
||||
if (old_cpu == PANIC_CPU_INVALID)
|
||||
/* atomic_try_cmpxchg updates old_cpu on failure */
|
||||
if (atomic_try_cmpxchg(&panic_cpu, &old_cpu, this_cpu))
|
||||
panic("%s", msg);
|
||||
else if (old_cpu != cpu)
|
||||
else if (old_cpu != this_cpu)
|
||||
nmi_panic_self_stop(regs);
|
||||
}
|
||||
EXPORT_SYMBOL(nmi_panic);
|
||||
|
|
@ -311,15 +312,18 @@ void panic(const char *fmt, ...)
|
|||
* stop themself or will wait until they are stopped by the 1st CPU
|
||||
* with smp_send_stop().
|
||||
*
|
||||
* `old_cpu == PANIC_CPU_INVALID' means this is the 1st CPU which
|
||||
* comes here, so go ahead.
|
||||
* cmpxchg success means this is the 1st CPU which comes here,
|
||||
* so go ahead.
|
||||
* `old_cpu == this_cpu' means we came from nmi_panic() which sets
|
||||
* panic_cpu to this CPU. In this case, this is also the 1st CPU.
|
||||
*/
|
||||
old_cpu = PANIC_CPU_INVALID;
|
||||
this_cpu = raw_smp_processor_id();
|
||||
old_cpu = atomic_cmpxchg(&panic_cpu, PANIC_CPU_INVALID, this_cpu);
|
||||
|
||||
if (old_cpu != PANIC_CPU_INVALID && old_cpu != this_cpu)
|
||||
/* atomic_try_cmpxchg updates old_cpu on failure */
|
||||
if (atomic_try_cmpxchg(&panic_cpu, &old_cpu, this_cpu)) {
|
||||
/* go ahead */
|
||||
} else if (old_cpu != this_cpu)
|
||||
panic_smp_self_stop();
|
||||
|
||||
console_verbose();
|
||||
|
|
|
|||
|
|
@ -286,12 +286,6 @@ static int pid_ns_ctl_handler(struct ctl_table *table, int write,
|
|||
if (write && !checkpoint_restore_ns_capable(pid_ns->user_ns))
|
||||
return -EPERM;
|
||||
|
||||
/*
|
||||
* Writing directly to ns' last_pid field is OK, since this field
|
||||
* is volatile in a living namespace anyway and a code writing to
|
||||
* it should synchronize its usage with external means.
|
||||
*/
|
||||
|
||||
next = idr_get_cursor(&pid_ns->idr) - 1;
|
||||
|
||||
tmp.data = &next;
|
||||
|
|
|
|||
|
|
@ -9869,7 +9869,7 @@ struct task_group root_task_group;
|
|||
LIST_HEAD(task_groups);
|
||||
|
||||
/* Cacheline aligned slab cache for task_group */
|
||||
static struct kmem_cache *task_group_cache __read_mostly;
|
||||
static struct kmem_cache *task_group_cache __ro_after_init;
|
||||
#endif
|
||||
|
||||
void __init sched_init(void)
|
||||
|
|
|
|||
|
|
@ -415,7 +415,7 @@ __sigqueue_alloc(int sig, struct task_struct *t, gfp_t gfp_flags,
|
|||
int override_rlimit, const unsigned int sigqueue_flags)
|
||||
{
|
||||
struct sigqueue *q = NULL;
|
||||
struct ucounts *ucounts = NULL;
|
||||
struct ucounts *ucounts;
|
||||
long sigpending;
|
||||
|
||||
/*
|
||||
|
|
@ -1058,12 +1058,11 @@ static void complete_signal(int sig, struct task_struct *p, enum pid_type type)
|
|||
signal->flags = SIGNAL_GROUP_EXIT;
|
||||
signal->group_exit_code = sig;
|
||||
signal->group_stop_count = 0;
|
||||
t = p;
|
||||
do {
|
||||
__for_each_thread(signal, t) {
|
||||
task_clear_jobctl_pending(t, JOBCTL_PENDING_MASK);
|
||||
sigaddset(&t->pending.signal, SIGKILL);
|
||||
signal_wake_up(t, 1);
|
||||
} while_each_thread(p, t);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -1471,16 +1470,21 @@ int group_send_sig_info(int sig, struct kernel_siginfo *info,
|
|||
int __kill_pgrp_info(int sig, struct kernel_siginfo *info, struct pid *pgrp)
|
||||
{
|
||||
struct task_struct *p = NULL;
|
||||
int retval, success;
|
||||
int ret = -ESRCH;
|
||||
|
||||
success = 0;
|
||||
retval = -ESRCH;
|
||||
do_each_pid_task(pgrp, PIDTYPE_PGID, p) {
|
||||
int err = group_send_sig_info(sig, info, p, PIDTYPE_PGID);
|
||||
success |= !err;
|
||||
retval = err;
|
||||
/*
|
||||
* If group_send_sig_info() succeeds at least once ret
|
||||
* becomes 0 and after that the code below has no effect.
|
||||
* Otherwise we return the last err or -ESRCH if this
|
||||
* process group is empty.
|
||||
*/
|
||||
if (ret)
|
||||
ret = err;
|
||||
} while_each_pid_task(pgrp, PIDTYPE_PGID, p);
|
||||
return success ? 0 : retval;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int kill_pid_info(int sig, struct kernel_siginfo *info, struct pid *pid)
|
||||
|
|
|
|||
|
|
@ -272,8 +272,7 @@ static void smpboot_destroy_threads(struct smp_hotplug_thread *ht)
|
|||
struct task_struct *tsk = *per_cpu_ptr(ht->store, cpu);
|
||||
|
||||
if (tsk) {
|
||||
kthread_stop(tsk);
|
||||
put_task_struct(tsk);
|
||||
kthread_stop_put(tsk);
|
||||
*per_cpu_ptr(ht->store, cpu) = NULL;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
41
kernel/sys.c
41
kernel/sys.c
|
|
@ -1786,6 +1786,7 @@ void getrusage(struct task_struct *p, int who, struct rusage *r)
|
|||
unsigned long flags;
|
||||
u64 tgutime, tgstime, utime, stime;
|
||||
unsigned long maxrss = 0;
|
||||
struct signal_struct *sig = p->signal;
|
||||
|
||||
memset((char *)r, 0, sizeof (*r));
|
||||
utime = stime = 0;
|
||||
|
|
@ -1793,7 +1794,7 @@ void getrusage(struct task_struct *p, int who, struct rusage *r)
|
|||
if (who == RUSAGE_THREAD) {
|
||||
task_cputime_adjusted(current, &utime, &stime);
|
||||
accumulate_thread_rusage(p, r);
|
||||
maxrss = p->signal->maxrss;
|
||||
maxrss = sig->maxrss;
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
@ -1803,15 +1804,15 @@ void getrusage(struct task_struct *p, int who, struct rusage *r)
|
|||
switch (who) {
|
||||
case RUSAGE_BOTH:
|
||||
case RUSAGE_CHILDREN:
|
||||
utime = p->signal->cutime;
|
||||
stime = p->signal->cstime;
|
||||
r->ru_nvcsw = p->signal->cnvcsw;
|
||||
r->ru_nivcsw = p->signal->cnivcsw;
|
||||
r->ru_minflt = p->signal->cmin_flt;
|
||||
r->ru_majflt = p->signal->cmaj_flt;
|
||||
r->ru_inblock = p->signal->cinblock;
|
||||
r->ru_oublock = p->signal->coublock;
|
||||
maxrss = p->signal->cmaxrss;
|
||||
utime = sig->cutime;
|
||||
stime = sig->cstime;
|
||||
r->ru_nvcsw = sig->cnvcsw;
|
||||
r->ru_nivcsw = sig->cnivcsw;
|
||||
r->ru_minflt = sig->cmin_flt;
|
||||
r->ru_majflt = sig->cmaj_flt;
|
||||
r->ru_inblock = sig->cinblock;
|
||||
r->ru_oublock = sig->coublock;
|
||||
maxrss = sig->cmaxrss;
|
||||
|
||||
if (who == RUSAGE_CHILDREN)
|
||||
break;
|
||||
|
|
@ -1821,18 +1822,16 @@ void getrusage(struct task_struct *p, int who, struct rusage *r)
|
|||
thread_group_cputime_adjusted(p, &tgutime, &tgstime);
|
||||
utime += tgutime;
|
||||
stime += tgstime;
|
||||
r->ru_nvcsw += p->signal->nvcsw;
|
||||
r->ru_nivcsw += p->signal->nivcsw;
|
||||
r->ru_minflt += p->signal->min_flt;
|
||||
r->ru_majflt += p->signal->maj_flt;
|
||||
r->ru_inblock += p->signal->inblock;
|
||||
r->ru_oublock += p->signal->oublock;
|
||||
if (maxrss < p->signal->maxrss)
|
||||
maxrss = p->signal->maxrss;
|
||||
t = p;
|
||||
do {
|
||||
r->ru_nvcsw += sig->nvcsw;
|
||||
r->ru_nivcsw += sig->nivcsw;
|
||||
r->ru_minflt += sig->min_flt;
|
||||
r->ru_majflt += sig->maj_flt;
|
||||
r->ru_inblock += sig->inblock;
|
||||
r->ru_oublock += sig->oublock;
|
||||
if (maxrss < sig->maxrss)
|
||||
maxrss = sig->maxrss;
|
||||
__for_each_thread(sig, t)
|
||||
accumulate_thread_rusage(t, r);
|
||||
} while_each_thread(p, t);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -233,9 +233,8 @@ static int fill_stats_for_tgid(pid_t tgid, struct taskstats *stats)
|
|||
else
|
||||
memset(stats, 0, sizeof(*stats));
|
||||
|
||||
tsk = first;
|
||||
start_time = ktime_get_ns();
|
||||
do {
|
||||
for_each_thread(first, tsk) {
|
||||
if (tsk->exit_state)
|
||||
continue;
|
||||
/*
|
||||
|
|
@ -258,7 +257,7 @@ static int fill_stats_for_tgid(pid_t tgid, struct taskstats *stats)
|
|||
|
||||
stats->nvcsw += tsk->nvcsw;
|
||||
stats->nivcsw += tsk->nivcsw;
|
||||
} while_each_thread(first, tsk);
|
||||
}
|
||||
|
||||
unlock_task_sighand(first, &flags);
|
||||
rc = 0;
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
#include <linux/bsearch.h>
|
||||
#include <linux/sort.h>
|
||||
|
||||
static struct kmem_cache *user_ns_cachep __read_mostly;
|
||||
static struct kmem_cache *user_ns_cachep __ro_after_init;
|
||||
static DEFINE_MUTEX(userns_state_mutex);
|
||||
|
||||
static bool new_idmap_permitted(const struct file *file,
|
||||
|
|
|
|||
|
|
@ -418,21 +418,21 @@ static struct workqueue_attrs *ordered_wq_attrs[NR_STD_WORKER_POOLS];
|
|||
* process context while holding a pool lock. Bounce to a dedicated kthread
|
||||
* worker to avoid A-A deadlocks.
|
||||
*/
|
||||
static struct kthread_worker *pwq_release_worker;
|
||||
static struct kthread_worker *pwq_release_worker __ro_after_init;
|
||||
|
||||
struct workqueue_struct *system_wq __read_mostly;
|
||||
struct workqueue_struct *system_wq __ro_after_init;
|
||||
EXPORT_SYMBOL(system_wq);
|
||||
struct workqueue_struct *system_highpri_wq __read_mostly;
|
||||
struct workqueue_struct *system_highpri_wq __ro_after_init;
|
||||
EXPORT_SYMBOL_GPL(system_highpri_wq);
|
||||
struct workqueue_struct *system_long_wq __read_mostly;
|
||||
struct workqueue_struct *system_long_wq __ro_after_init;
|
||||
EXPORT_SYMBOL_GPL(system_long_wq);
|
||||
struct workqueue_struct *system_unbound_wq __read_mostly;
|
||||
struct workqueue_struct *system_unbound_wq __ro_after_init;
|
||||
EXPORT_SYMBOL_GPL(system_unbound_wq);
|
||||
struct workqueue_struct *system_freezable_wq __read_mostly;
|
||||
struct workqueue_struct *system_freezable_wq __ro_after_init;
|
||||
EXPORT_SYMBOL_GPL(system_freezable_wq);
|
||||
struct workqueue_struct *system_power_efficient_wq __read_mostly;
|
||||
struct workqueue_struct *system_power_efficient_wq __ro_after_init;
|
||||
EXPORT_SYMBOL_GPL(system_power_efficient_wq);
|
||||
struct workqueue_struct *system_freezable_power_efficient_wq __read_mostly;
|
||||
struct workqueue_struct *system_freezable_power_efficient_wq __ro_after_init;
|
||||
EXPORT_SYMBOL_GPL(system_freezable_power_efficient_wq);
|
||||
|
||||
static int worker_thread(void *__worker);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue