Merge branch 'locking/urgent' into locking/core, to pick up fixes
Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
@@ -681,7 +681,7 @@ static struct audit_rule_data *audit_krule_to_data(struct audit_krule *krule)
|
||||
data->values[i] = AUDIT_UID_UNSET;
|
||||
break;
|
||||
}
|
||||
/* fall through - if set */
|
||||
fallthrough; /* if set */
|
||||
default:
|
||||
data->values[i] = f->val;
|
||||
}
|
||||
|
||||
+1
-1
@@ -1794,7 +1794,7 @@ static bool cg_sockopt_is_valid_access(int off, int size,
|
||||
return prog->expected_attach_type ==
|
||||
BPF_CGROUP_GETSOCKOPT;
|
||||
case offsetof(struct bpf_sockopt, optname):
|
||||
/* fallthrough */
|
||||
fallthrough;
|
||||
case offsetof(struct bpf_sockopt, level):
|
||||
if (size != size_default)
|
||||
return false;
|
||||
|
||||
+1
-1
@@ -279,7 +279,7 @@ static int cpu_map_bpf_prog_run_xdp(struct bpf_cpu_map_entry *rcpu,
|
||||
break;
|
||||
default:
|
||||
bpf_warn_invalid_xdp_action(act);
|
||||
/* fallthrough */
|
||||
fallthrough;
|
||||
case XDP_DROP:
|
||||
xdp_return_frame(xdpf);
|
||||
stats->drop++;
|
||||
|
||||
+4
-11
@@ -1622,7 +1622,6 @@ struct bpf_iter_seq_hash_map_info {
|
||||
struct bpf_map *map;
|
||||
struct bpf_htab *htab;
|
||||
void *percpu_value_buf; // non-zero means percpu hash
|
||||
unsigned long flags;
|
||||
u32 bucket_id;
|
||||
u32 skip_elems;
|
||||
};
|
||||
@@ -1632,7 +1631,6 @@ bpf_hash_map_seq_find_next(struct bpf_iter_seq_hash_map_info *info,
|
||||
struct htab_elem *prev_elem)
|
||||
{
|
||||
const struct bpf_htab *htab = info->htab;
|
||||
unsigned long flags = info->flags;
|
||||
u32 skip_elems = info->skip_elems;
|
||||
u32 bucket_id = info->bucket_id;
|
||||
struct hlist_nulls_head *head;
|
||||
@@ -1656,19 +1654,18 @@ bpf_hash_map_seq_find_next(struct bpf_iter_seq_hash_map_info *info,
|
||||
|
||||
/* not found, unlock and go to the next bucket */
|
||||
b = &htab->buckets[bucket_id++];
|
||||
htab_unlock_bucket(htab, b, flags);
|
||||
rcu_read_unlock();
|
||||
skip_elems = 0;
|
||||
}
|
||||
|
||||
for (i = bucket_id; i < htab->n_buckets; i++) {
|
||||
b = &htab->buckets[i];
|
||||
flags = htab_lock_bucket(htab, b);
|
||||
rcu_read_lock();
|
||||
|
||||
count = 0;
|
||||
head = &b->head;
|
||||
hlist_nulls_for_each_entry_rcu(elem, n, head, hash_node) {
|
||||
if (count >= skip_elems) {
|
||||
info->flags = flags;
|
||||
info->bucket_id = i;
|
||||
info->skip_elems = count;
|
||||
return elem;
|
||||
@@ -1676,7 +1673,7 @@ bpf_hash_map_seq_find_next(struct bpf_iter_seq_hash_map_info *info,
|
||||
count++;
|
||||
}
|
||||
|
||||
htab_unlock_bucket(htab, b, flags);
|
||||
rcu_read_unlock();
|
||||
skip_elems = 0;
|
||||
}
|
||||
|
||||
@@ -1754,14 +1751,10 @@ static int bpf_hash_map_seq_show(struct seq_file *seq, void *v)
|
||||
|
||||
static void bpf_hash_map_seq_stop(struct seq_file *seq, void *v)
|
||||
{
|
||||
struct bpf_iter_seq_hash_map_info *info = seq->private;
|
||||
|
||||
if (!v)
|
||||
(void)__bpf_hash_map_seq_show(seq, NULL);
|
||||
else
|
||||
htab_unlock_bucket(info->htab,
|
||||
&info->htab->buckets[info->bucket_id],
|
||||
info->flags);
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
static int bpf_iter_init_hash_map(void *priv_data,
|
||||
|
||||
+3
-1
@@ -226,10 +226,12 @@ static void *map_seq_next(struct seq_file *m, void *v, loff_t *pos)
|
||||
else
|
||||
prev_key = key;
|
||||
|
||||
rcu_read_lock();
|
||||
if (map->ops->map_get_next_key(map, prev_key, key)) {
|
||||
map_iter(m)->done = true;
|
||||
return NULL;
|
||||
key = NULL;
|
||||
}
|
||||
rcu_read_unlock();
|
||||
return key;
|
||||
}
|
||||
|
||||
|
||||
@@ -2029,7 +2029,7 @@ bpf_prog_load_check_attach(enum bpf_prog_type prog_type,
|
||||
case BPF_PROG_TYPE_EXT:
|
||||
if (expected_attach_type)
|
||||
return -EINVAL;
|
||||
/* fallthrough */
|
||||
fallthrough;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@@ -2634,7 +2634,7 @@ static int bpf_raw_tp_link_fill_link_info(const struct bpf_link *link,
|
||||
u32 ulen = info->raw_tracepoint.tp_name_len;
|
||||
size_t tp_len = strlen(tp_name);
|
||||
|
||||
if (ulen && !ubuf)
|
||||
if (!ulen ^ !ubuf)
|
||||
return -EINVAL;
|
||||
|
||||
info->raw_tracepoint.tp_name_len = tp_len + 1;
|
||||
|
||||
@@ -30,15 +30,15 @@ static struct kobject *btf_kobj;
|
||||
|
||||
static int __init btf_vmlinux_init(void)
|
||||
{
|
||||
if (!__start_BTF)
|
||||
bin_attr_btf_vmlinux.size = __stop_BTF - __start_BTF;
|
||||
|
||||
if (!__start_BTF || bin_attr_btf_vmlinux.size == 0)
|
||||
return 0;
|
||||
|
||||
btf_kobj = kobject_create_and_add("btf", kernel_kobj);
|
||||
if (!btf_kobj)
|
||||
return -ENOMEM;
|
||||
|
||||
bin_attr_btf_vmlinux.size = __stop_BTF - __start_BTF;
|
||||
|
||||
return sysfs_create_bin_file(btf_kobj, &bin_attr_btf_vmlinux);
|
||||
}
|
||||
|
||||
|
||||
@@ -5236,7 +5236,7 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env,
|
||||
off_reg == dst_reg ? dst : src);
|
||||
return -EACCES;
|
||||
}
|
||||
/* fall-through */
|
||||
fallthrough;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -5667,8 +5667,8 @@ static void scalar32_min_max_or(struct bpf_reg_state *dst_reg,
|
||||
bool src_known = tnum_subreg_is_const(src_reg->var_off);
|
||||
bool dst_known = tnum_subreg_is_const(dst_reg->var_off);
|
||||
struct tnum var32_off = tnum_subreg(dst_reg->var_off);
|
||||
s32 smin_val = src_reg->smin_value;
|
||||
u32 umin_val = src_reg->umin_value;
|
||||
s32 smin_val = src_reg->s32_min_value;
|
||||
u32 umin_val = src_reg->u32_min_value;
|
||||
|
||||
/* Assuming scalar64_min_max_or will be called so it is safe
|
||||
* to skip updating register for known case.
|
||||
@@ -5691,8 +5691,8 @@ static void scalar32_min_max_or(struct bpf_reg_state *dst_reg,
|
||||
/* ORing two positives gives a positive, so safe to
|
||||
* cast result into s64.
|
||||
*/
|
||||
dst_reg->s32_min_value = dst_reg->umin_value;
|
||||
dst_reg->s32_max_value = dst_reg->umax_value;
|
||||
dst_reg->s32_min_value = dst_reg->u32_min_value;
|
||||
dst_reg->s32_max_value = dst_reg->u32_max_value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10988,7 +10988,7 @@ static int check_attach_btf_id(struct bpf_verifier_env *env)
|
||||
default:
|
||||
if (!prog_extension)
|
||||
return -EINVAL;
|
||||
/* fallthrough */
|
||||
fallthrough;
|
||||
case BPF_MODIFY_RETURN:
|
||||
case BPF_LSM_MAC:
|
||||
case BPF_TRACE_FENTRY:
|
||||
|
||||
+1
-1
@@ -93,7 +93,7 @@ static int cap_validate_magic(cap_user_header_t header, unsigned *tocopy)
|
||||
break;
|
||||
case _LINUX_CAPABILITY_VERSION_2:
|
||||
warn_deprecated_v2();
|
||||
/* fall through - v3 is otherwise equivalent to v2. */
|
||||
fallthrough; /* v3 is otherwise equivalent to v2 */
|
||||
case _LINUX_CAPABILITY_VERSION_3:
|
||||
*tocopy = _LINUX_CAPABILITY_U32S_3;
|
||||
break;
|
||||
|
||||
+3
-3
@@ -255,11 +255,11 @@ get_compat_sigset(sigset_t *set, const compat_sigset_t __user *compat)
|
||||
return -EFAULT;
|
||||
switch (_NSIG_WORDS) {
|
||||
case 4: set->sig[3] = v.sig[6] | (((long)v.sig[7]) << 32 );
|
||||
/* fall through */
|
||||
fallthrough;
|
||||
case 3: set->sig[2] = v.sig[4] | (((long)v.sig[5]) << 32 );
|
||||
/* fall through */
|
||||
fallthrough;
|
||||
case 2: set->sig[1] = v.sig[2] | (((long)v.sig[3]) << 32 );
|
||||
/* fall through */
|
||||
fallthrough;
|
||||
case 1: set->sig[0] = v.sig[0] | (((long)v.sig[1]) << 32 );
|
||||
}
|
||||
#else
|
||||
|
||||
@@ -1046,14 +1046,14 @@ int gdb_serial_stub(struct kgdb_state *ks)
|
||||
return DBG_PASS_EVENT;
|
||||
}
|
||||
#endif
|
||||
/* Fall through */
|
||||
fallthrough;
|
||||
case 'C': /* Exception passing */
|
||||
tmp = gdb_cmd_exception_pass(ks);
|
||||
if (tmp > 0)
|
||||
goto default_handle;
|
||||
if (tmp == 0)
|
||||
break;
|
||||
/* Fall through - on tmp < 0 */
|
||||
fallthrough; /* on tmp < 0 */
|
||||
case 'c': /* Continue packet */
|
||||
case 's': /* Single step packet */
|
||||
if (kgdb_contthread && kgdb_contthread != current) {
|
||||
@@ -1062,7 +1062,7 @@ int gdb_serial_stub(struct kgdb_state *ks)
|
||||
break;
|
||||
}
|
||||
dbg_activate_sw_breakpoints();
|
||||
/* Fall through - to default processing */
|
||||
fallthrough; /* to default processing */
|
||||
default:
|
||||
default_handle:
|
||||
error = kgdb_arch_handle_exception(ks->ex_vector,
|
||||
|
||||
@@ -173,11 +173,11 @@ int kdb_get_kbd_char(void)
|
||||
case KT_LATIN:
|
||||
if (isprint(keychar))
|
||||
break; /* printable characters */
|
||||
/* fall through */
|
||||
fallthrough;
|
||||
case KT_SPEC:
|
||||
if (keychar == K_ENTER)
|
||||
break;
|
||||
/* fall through */
|
||||
fallthrough;
|
||||
default:
|
||||
return -1; /* ignore unprintables */
|
||||
}
|
||||
|
||||
@@ -432,7 +432,7 @@ int kdb_getphysword(unsigned long *word, unsigned long addr, size_t size)
|
||||
*word = w8;
|
||||
break;
|
||||
}
|
||||
/* fall through */
|
||||
fallthrough;
|
||||
default:
|
||||
diag = KDB_BADWIDTH;
|
||||
kdb_printf("kdb_getphysword: bad width %ld\n", (long) size);
|
||||
@@ -481,7 +481,7 @@ int kdb_getword(unsigned long *word, unsigned long addr, size_t size)
|
||||
*word = w8;
|
||||
break;
|
||||
}
|
||||
/* fall through */
|
||||
fallthrough;
|
||||
default:
|
||||
diag = KDB_BADWIDTH;
|
||||
kdb_printf("kdb_getword: bad width %ld\n", (long) size);
|
||||
@@ -525,7 +525,7 @@ int kdb_putword(unsigned long addr, unsigned long word, size_t size)
|
||||
diag = kdb_putarea(addr, w8);
|
||||
break;
|
||||
}
|
||||
/* fall through */
|
||||
fallthrough;
|
||||
default:
|
||||
diag = KDB_BADWIDTH;
|
||||
kdb_printf("kdb_putword: bad width %ld\n", (long) size);
|
||||
|
||||
+1
-1
@@ -84,7 +84,7 @@ static int atomic_pool_expand(struct gen_pool *pool, size_t pool_size,
|
||||
gfp_t gfp)
|
||||
{
|
||||
unsigned int order;
|
||||
struct page *page;
|
||||
struct page *page = NULL;
|
||||
void *addr;
|
||||
int ret = -ENOMEM;
|
||||
|
||||
|
||||
+33
-8
@@ -60,29 +60,54 @@ static long syscall_trace_enter(struct pt_regs *regs, long syscall,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Either of the above might have changed the syscall number */
|
||||
syscall = syscall_get_nr(current, regs);
|
||||
|
||||
if (unlikely(ti_work & _TIF_SYSCALL_TRACEPOINT))
|
||||
trace_sys_enter(regs, syscall);
|
||||
|
||||
syscall_enter_audit(regs, syscall);
|
||||
|
||||
/* The above might have changed the syscall number */
|
||||
return ret ? : syscall_get_nr(current, regs);
|
||||
return ret ? : syscall;
|
||||
}
|
||||
|
||||
static __always_inline long
|
||||
__syscall_enter_from_user_work(struct pt_regs *regs, long syscall)
|
||||
{
|
||||
unsigned long ti_work;
|
||||
|
||||
ti_work = READ_ONCE(current_thread_info()->flags);
|
||||
if (ti_work & SYSCALL_ENTER_WORK)
|
||||
syscall = syscall_trace_enter(regs, syscall, ti_work);
|
||||
|
||||
return syscall;
|
||||
}
|
||||
|
||||
long syscall_enter_from_user_mode_work(struct pt_regs *regs, long syscall)
|
||||
{
|
||||
return __syscall_enter_from_user_work(regs, syscall);
|
||||
}
|
||||
|
||||
noinstr long syscall_enter_from_user_mode(struct pt_regs *regs, long syscall)
|
||||
{
|
||||
unsigned long ti_work;
|
||||
long ret;
|
||||
|
||||
enter_from_user_mode(regs);
|
||||
instrumentation_begin();
|
||||
|
||||
instrumentation_begin();
|
||||
local_irq_enable();
|
||||
ti_work = READ_ONCE(current_thread_info()->flags);
|
||||
if (ti_work & SYSCALL_ENTER_WORK)
|
||||
syscall = syscall_trace_enter(regs, syscall, ti_work);
|
||||
ret = __syscall_enter_from_user_work(regs, syscall);
|
||||
instrumentation_end();
|
||||
|
||||
return syscall;
|
||||
return ret;
|
||||
}
|
||||
|
||||
noinstr void syscall_enter_from_user_mode_prepare(struct pt_regs *regs)
|
||||
{
|
||||
enter_from_user_mode(regs);
|
||||
instrumentation_begin();
|
||||
local_irq_enable();
|
||||
instrumentation_end();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -10034,7 +10034,7 @@ perf_event_parse_addr_filter(struct perf_event *event, char *fstr,
|
||||
case IF_SRC_KERNELADDR:
|
||||
case IF_SRC_KERNEL:
|
||||
kernel = 1;
|
||||
/* fall through */
|
||||
fallthrough;
|
||||
|
||||
case IF_SRC_FILEADDR:
|
||||
case IF_SRC_FILE:
|
||||
|
||||
+3
-2
@@ -589,7 +589,7 @@ static __latent_entropy int dup_mmap(struct mm_struct *mm,
|
||||
|
||||
mm->map_count++;
|
||||
if (!(tmp->vm_flags & VM_WIPEONFORK))
|
||||
retval = copy_page_range(mm, oldmm, mpnt);
|
||||
retval = copy_page_range(mm, oldmm, mpnt, tmp);
|
||||
|
||||
if (tmp->vm_ops && tmp->vm_ops->open)
|
||||
tmp->vm_ops->open(tmp);
|
||||
@@ -1011,6 +1011,7 @@ static struct mm_struct *mm_init(struct mm_struct *mm, struct task_struct *p,
|
||||
mm_pgtables_bytes_init(mm);
|
||||
mm->map_count = 0;
|
||||
mm->locked_vm = 0;
|
||||
atomic_set(&mm->has_pinned, 0);
|
||||
atomic64_set(&mm->pinned_vm, 0);
|
||||
memset(&mm->rss_stat, 0, sizeof(mm->rss_stat));
|
||||
spin_lock_init(&mm->page_table_lock);
|
||||
@@ -3014,7 +3015,7 @@ int unshare_files(struct files_struct **displaced)
|
||||
}
|
||||
|
||||
int sysctl_max_threads(struct ctl_table *table, int write,
|
||||
void __user *buffer, size_t *lenp, loff_t *ppos)
|
||||
void *buffer, size_t *lenp, loff_t *ppos)
|
||||
{
|
||||
struct ctl_table t;
|
||||
int ret;
|
||||
|
||||
@@ -19,7 +19,9 @@
|
||||
#include <linux/vmalloc.h>
|
||||
#include "gcov.h"
|
||||
|
||||
#if (__GNUC__ >= 7)
|
||||
#if (__GNUC__ >= 10)
|
||||
#define GCOV_COUNTERS 8
|
||||
#elif (__GNUC__ >= 7)
|
||||
#define GCOV_COUNTERS 9
|
||||
#elif (__GNUC__ > 5) || (__GNUC__ == 5 && __GNUC_MINOR__ >= 1)
|
||||
#define GCOV_COUNTERS 10
|
||||
|
||||
+1
-1
@@ -173,7 +173,7 @@ irqreturn_t __handle_irq_event_percpu(struct irq_desc *desc, unsigned int *flags
|
||||
|
||||
__irq_wake_thread(desc, action);
|
||||
|
||||
/* Fall through - to add to randomness */
|
||||
fallthrough; /* to add to randomness */
|
||||
case IRQ_HANDLED:
|
||||
*flags |= action->flags;
|
||||
break;
|
||||
|
||||
+2
-2
@@ -271,7 +271,7 @@ int irq_do_set_affinity(struct irq_data *data, const struct cpumask *mask,
|
||||
case IRQ_SET_MASK_OK:
|
||||
case IRQ_SET_MASK_OK_DONE:
|
||||
cpumask_copy(desc->irq_common_data.affinity, mask);
|
||||
/* fall through */
|
||||
fallthrough;
|
||||
case IRQ_SET_MASK_OK_NOCOPY:
|
||||
irq_validate_effective_affinity(data);
|
||||
irq_set_thread_affinity(desc);
|
||||
@@ -868,7 +868,7 @@ int __irq_set_trigger(struct irq_desc *desc, unsigned long flags)
|
||||
case IRQ_SET_MASK_OK_DONE:
|
||||
irqd_clear(&desc->irq_data, IRQD_TRIGGER_MASK);
|
||||
irqd_set(&desc->irq_data, flags);
|
||||
/* fall through */
|
||||
fallthrough;
|
||||
|
||||
case IRQ_SET_MASK_OK_NOCOPY:
|
||||
flags = irqd_get_trigger_type(&desc->irq_data);
|
||||
|
||||
@@ -380,6 +380,13 @@ int irq_matrix_alloc(struct irq_matrix *m, const struct cpumask *msk,
|
||||
unsigned int cpu, bit;
|
||||
struct cpumap *cm;
|
||||
|
||||
/*
|
||||
* Not required in theory, but matrix_find_best_cpu() uses
|
||||
* for_each_cpu() which ignores the cpumask on UP .
|
||||
*/
|
||||
if (cpumask_empty(msk))
|
||||
return -EINVAL;
|
||||
|
||||
cpu = matrix_find_best_cpu(m, msk);
|
||||
if (cpu == UINT_MAX)
|
||||
return -ENOSPC;
|
||||
|
||||
+2
-2
@@ -684,12 +684,12 @@ bool kallsyms_show_value(const struct cred *cred)
|
||||
case 0:
|
||||
if (kallsyms_for_perf())
|
||||
return true;
|
||||
/* fallthrough */
|
||||
fallthrough;
|
||||
case 1:
|
||||
if (security_capable(cred, &init_user_ns, CAP_SYSLOG,
|
||||
CAP_OPT_NOAUDIT) == 0)
|
||||
return true;
|
||||
/* fallthrough */
|
||||
fallthrough;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
+33
-3
@@ -2140,6 +2140,9 @@ static void kill_kprobe(struct kprobe *p)
|
||||
|
||||
lockdep_assert_held(&kprobe_mutex);
|
||||
|
||||
if (WARN_ON_ONCE(kprobe_gone(p)))
|
||||
return;
|
||||
|
||||
p->flags |= KPROBE_FLAG_GONE;
|
||||
if (kprobe_aggrprobe(p)) {
|
||||
/*
|
||||
@@ -2159,9 +2162,10 @@ static void kill_kprobe(struct kprobe *p)
|
||||
|
||||
/*
|
||||
* The module is going away. We should disarm the kprobe which
|
||||
* is using ftrace.
|
||||
* is using ftrace, because ftrace framework is still available at
|
||||
* MODULE_STATE_GOING notification.
|
||||
*/
|
||||
if (kprobe_ftrace(p))
|
||||
if (kprobe_ftrace(p) && !kprobe_disabled(p) && !kprobes_all_disarmed)
|
||||
disarm_kprobe_ftrace(p);
|
||||
}
|
||||
|
||||
@@ -2419,7 +2423,10 @@ static int kprobes_module_callback(struct notifier_block *nb,
|
||||
mutex_lock(&kprobe_mutex);
|
||||
for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
|
||||
head = &kprobe_table[i];
|
||||
hlist_for_each_entry(p, head, hlist)
|
||||
hlist_for_each_entry(p, head, hlist) {
|
||||
if (kprobe_gone(p))
|
||||
continue;
|
||||
|
||||
if (within_module_init((unsigned long)p->addr, mod) ||
|
||||
(checkcore &&
|
||||
within_module_core((unsigned long)p->addr, mod))) {
|
||||
@@ -2436,6 +2443,7 @@ static int kprobes_module_callback(struct notifier_block *nb,
|
||||
*/
|
||||
kill_kprobe(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (val == MODULE_STATE_GOING)
|
||||
remove_module_kprobe_blacklist(mod);
|
||||
@@ -2452,6 +2460,28 @@ static struct notifier_block kprobe_module_nb = {
|
||||
extern unsigned long __start_kprobe_blacklist[];
|
||||
extern unsigned long __stop_kprobe_blacklist[];
|
||||
|
||||
void kprobe_free_init_mem(void)
|
||||
{
|
||||
void *start = (void *)(&__init_begin);
|
||||
void *end = (void *)(&__init_end);
|
||||
struct hlist_head *head;
|
||||
struct kprobe *p;
|
||||
int i;
|
||||
|
||||
mutex_lock(&kprobe_mutex);
|
||||
|
||||
/* Kill all kprobes on initmem */
|
||||
for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
|
||||
head = &kprobe_table[i];
|
||||
hlist_for_each_entry(p, head, hlist) {
|
||||
if (start <= (void *)p->addr && (void *)p->addr < end)
|
||||
kill_kprobe(p);
|
||||
}
|
||||
}
|
||||
|
||||
mutex_unlock(&kprobe_mutex);
|
||||
}
|
||||
|
||||
static int __init init_kprobes(void)
|
||||
{
|
||||
int i, err = 0;
|
||||
|
||||
+97
-57
@@ -76,6 +76,23 @@ module_param(lock_stat, int, 0644);
|
||||
#define lock_stat 0
|
||||
#endif
|
||||
|
||||
DEFINE_PER_CPU(unsigned int, lockdep_recursion);
|
||||
EXPORT_PER_CPU_SYMBOL_GPL(lockdep_recursion);
|
||||
|
||||
static inline bool lockdep_enabled(void)
|
||||
{
|
||||
if (!debug_locks)
|
||||
return false;
|
||||
|
||||
if (raw_cpu_read(lockdep_recursion))
|
||||
return false;
|
||||
|
||||
if (current->lockdep_recursion)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* lockdep_lock: protects the lockdep graph, the hashes and the
|
||||
* class/list/hash allocators.
|
||||
@@ -93,7 +110,7 @@ static inline void lockdep_lock(void)
|
||||
|
||||
arch_spin_lock(&__lock);
|
||||
__owner = current;
|
||||
current->lockdep_recursion++;
|
||||
__this_cpu_inc(lockdep_recursion);
|
||||
}
|
||||
|
||||
static inline void lockdep_unlock(void)
|
||||
@@ -101,7 +118,7 @@ static inline void lockdep_unlock(void)
|
||||
if (debug_locks && DEBUG_LOCKS_WARN_ON(__owner != current))
|
||||
return;
|
||||
|
||||
current->lockdep_recursion--;
|
||||
__this_cpu_dec(lockdep_recursion);
|
||||
__owner = NULL;
|
||||
arch_spin_unlock(&__lock);
|
||||
}
|
||||
@@ -408,10 +425,15 @@ void lockdep_init_task(struct task_struct *task)
|
||||
task->lockdep_recursion = 0;
|
||||
}
|
||||
|
||||
static __always_inline void lockdep_recursion_inc(void)
|
||||
{
|
||||
__this_cpu_inc(lockdep_recursion);
|
||||
}
|
||||
|
||||
static __always_inline void lockdep_recursion_finish(void)
|
||||
{
|
||||
if (WARN_ON_ONCE((--current->lockdep_recursion) & LOCKDEP_RECURSION_MASK))
|
||||
current->lockdep_recursion = 0;
|
||||
if (WARN_ON_ONCE(__this_cpu_dec_return(lockdep_recursion)))
|
||||
__this_cpu_write(lockdep_recursion, 0);
|
||||
}
|
||||
|
||||
void lockdep_set_selftest_task(struct task_struct *task)
|
||||
@@ -600,6 +622,8 @@ static const char *usage_str[] =
|
||||
#include "lockdep_states.h"
|
||||
#undef LOCKDEP_STATE
|
||||
[LOCK_USED] = "INITIAL USE",
|
||||
[LOCK_USED_READ] = "INITIAL READ USE",
|
||||
/* abused as string storage for verify_lock_unused() */
|
||||
[LOCK_USAGE_STATES] = "IN-NMI",
|
||||
};
|
||||
#endif
|
||||
@@ -2252,7 +2276,7 @@ static void print_lock_class_header(struct lock_class *class, int depth)
|
||||
#endif
|
||||
printk(KERN_CONT " {\n");
|
||||
|
||||
for (bit = 0; bit < LOCK_USAGE_STATES; bit++) {
|
||||
for (bit = 0; bit < LOCK_TRACE_STATES; bit++) {
|
||||
if (class->usage_mask & (1 << bit)) {
|
||||
int len = depth;
|
||||
|
||||
@@ -4033,7 +4057,7 @@ void lockdep_hardirqs_on_prepare(unsigned long ip)
|
||||
if (unlikely(in_nmi()))
|
||||
return;
|
||||
|
||||
if (unlikely(current->lockdep_recursion & LOCKDEP_RECURSION_MASK))
|
||||
if (unlikely(__this_cpu_read(lockdep_recursion)))
|
||||
return;
|
||||
|
||||
if (unlikely(lockdep_hardirqs_enabled())) {
|
||||
@@ -4069,7 +4093,7 @@ void lockdep_hardirqs_on_prepare(unsigned long ip)
|
||||
|
||||
current->hardirq_chain_key = current->curr_chain_key;
|
||||
|
||||
current->lockdep_recursion++;
|
||||
lockdep_recursion_inc();
|
||||
__trace_hardirqs_on_caller();
|
||||
lockdep_recursion_finish();
|
||||
}
|
||||
@@ -4102,7 +4126,7 @@ void noinstr lockdep_hardirqs_on(unsigned long ip)
|
||||
goto skip_checks;
|
||||
}
|
||||
|
||||
if (unlikely(current->lockdep_recursion & LOCKDEP_RECURSION_MASK))
|
||||
if (unlikely(__this_cpu_read(lockdep_recursion)))
|
||||
return;
|
||||
|
||||
if (lockdep_hardirqs_enabled()) {
|
||||
@@ -4155,7 +4179,7 @@ void noinstr lockdep_hardirqs_off(unsigned long ip)
|
||||
if (in_nmi()) {
|
||||
if (!IS_ENABLED(CONFIG_TRACE_IRQFLAGS_NMI))
|
||||
return;
|
||||
} else if (current->lockdep_recursion & LOCKDEP_RECURSION_MASK)
|
||||
} else if (__this_cpu_read(lockdep_recursion))
|
||||
return;
|
||||
|
||||
/*
|
||||
@@ -4188,7 +4212,7 @@ void lockdep_softirqs_on(unsigned long ip)
|
||||
{
|
||||
struct irqtrace_events *trace = ¤t->irqtrace;
|
||||
|
||||
if (unlikely(!debug_locks || current->lockdep_recursion))
|
||||
if (unlikely(!lockdep_enabled()))
|
||||
return;
|
||||
|
||||
/*
|
||||
@@ -4203,7 +4227,7 @@ void lockdep_softirqs_on(unsigned long ip)
|
||||
return;
|
||||
}
|
||||
|
||||
current->lockdep_recursion++;
|
||||
lockdep_recursion_inc();
|
||||
/*
|
||||
* We'll do an OFF -> ON transition:
|
||||
*/
|
||||
@@ -4226,7 +4250,7 @@ void lockdep_softirqs_on(unsigned long ip)
|
||||
*/
|
||||
void lockdep_softirqs_off(unsigned long ip)
|
||||
{
|
||||
if (unlikely(!debug_locks || current->lockdep_recursion))
|
||||
if (unlikely(!lockdep_enabled()))
|
||||
return;
|
||||
|
||||
/*
|
||||
@@ -4345,13 +4369,18 @@ static int separate_irq_context(struct task_struct *curr,
|
||||
static int mark_lock(struct task_struct *curr, struct held_lock *this,
|
||||
enum lock_usage_bit new_bit)
|
||||
{
|
||||
unsigned int new_mask = 1 << new_bit, ret = 1;
|
||||
unsigned int new_mask, ret = 1;
|
||||
|
||||
if (new_bit >= LOCK_USAGE_STATES) {
|
||||
DEBUG_LOCKS_WARN_ON(1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (new_bit == LOCK_USED && this->read)
|
||||
new_bit = LOCK_USED_READ;
|
||||
|
||||
new_mask = 1 << new_bit;
|
||||
|
||||
/*
|
||||
* If already set then do not dirty the cacheline,
|
||||
* nor do any checks:
|
||||
@@ -4364,26 +4393,32 @@ static int mark_lock(struct task_struct *curr, struct held_lock *this,
|
||||
/*
|
||||
* Make sure we didn't race:
|
||||
*/
|
||||
if (unlikely(hlock_class(this)->usage_mask & new_mask)) {
|
||||
graph_unlock();
|
||||
return 1;
|
||||
}
|
||||
if (unlikely(hlock_class(this)->usage_mask & new_mask))
|
||||
goto unlock;
|
||||
|
||||
hlock_class(this)->usage_mask |= new_mask;
|
||||
|
||||
if (!(hlock_class(this)->usage_traces[new_bit] = save_trace()))
|
||||
return 0;
|
||||
|
||||
switch (new_bit) {
|
||||
case LOCK_USED:
|
||||
debug_atomic_dec(nr_unused_locks);
|
||||
break;
|
||||
default:
|
||||
ret = mark_lock_irq(curr, this, new_bit);
|
||||
if (!ret)
|
||||
if (new_bit < LOCK_TRACE_STATES) {
|
||||
if (!(hlock_class(this)->usage_traces[new_bit] = save_trace()))
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (new_bit) {
|
||||
case 0 ... LOCK_USED-1:
|
||||
ret = mark_lock_irq(curr, this, new_bit);
|
||||
if (!ret)
|
||||
return 0;
|
||||
break;
|
||||
|
||||
case LOCK_USED:
|
||||
debug_atomic_dec(nr_unused_locks);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
unlock:
|
||||
graph_unlock();
|
||||
|
||||
/*
|
||||
@@ -4596,11 +4631,11 @@ void lockdep_init_map_waits(struct lockdep_map *lock, const char *name,
|
||||
if (subclass) {
|
||||
unsigned long flags;
|
||||
|
||||
if (DEBUG_LOCKS_WARN_ON(current->lockdep_recursion))
|
||||
if (DEBUG_LOCKS_WARN_ON(!lockdep_enabled()))
|
||||
return;
|
||||
|
||||
raw_local_irq_save(flags);
|
||||
current->lockdep_recursion++;
|
||||
lockdep_recursion_inc();
|
||||
register_lock_class(lock, subclass, 1);
|
||||
lockdep_recursion_finish();
|
||||
raw_local_irq_restore(flags);
|
||||
@@ -5283,11 +5318,11 @@ void lock_set_class(struct lockdep_map *lock, const char *name,
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
if (unlikely(current->lockdep_recursion))
|
||||
if (unlikely(!lockdep_enabled()))
|
||||
return;
|
||||
|
||||
raw_local_irq_save(flags);
|
||||
current->lockdep_recursion++;
|
||||
lockdep_recursion_inc();
|
||||
check_flags(flags);
|
||||
if (__lock_set_class(lock, name, key, subclass, ip))
|
||||
check_chain_key(current);
|
||||
@@ -5300,11 +5335,11 @@ void lock_downgrade(struct lockdep_map *lock, unsigned long ip)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
if (unlikely(current->lockdep_recursion))
|
||||
if (unlikely(!lockdep_enabled()))
|
||||
return;
|
||||
|
||||
raw_local_irq_save(flags);
|
||||
current->lockdep_recursion++;
|
||||
lockdep_recursion_inc();
|
||||
check_flags(flags);
|
||||
if (__lock_downgrade(lock, ip))
|
||||
check_chain_key(current);
|
||||
@@ -5318,12 +5353,20 @@ static void verify_lock_unused(struct lockdep_map *lock, struct held_lock *hlock
|
||||
{
|
||||
#ifdef CONFIG_PROVE_LOCKING
|
||||
struct lock_class *class = look_up_lock_class(lock, subclass);
|
||||
unsigned long mask = LOCKF_USED;
|
||||
|
||||
/* if it doesn't have a class (yet), it certainly hasn't been used yet */
|
||||
if (!class)
|
||||
return;
|
||||
|
||||
if (!(class->usage_mask & LOCK_USED))
|
||||
/*
|
||||
* READ locks only conflict with USED, such that if we only ever use
|
||||
* READ locks, there is no deadlock possible -- RCU.
|
||||
*/
|
||||
if (!hlock->read)
|
||||
mask |= LOCKF_USED_READ;
|
||||
|
||||
if (!(class->usage_mask & mask))
|
||||
return;
|
||||
|
||||
hlock->class_idx = class - lock_classes;
|
||||
@@ -5334,7 +5377,7 @@ static void verify_lock_unused(struct lockdep_map *lock, struct held_lock *hlock
|
||||
|
||||
static bool lockdep_nmi(void)
|
||||
{
|
||||
if (current->lockdep_recursion & LOCKDEP_RECURSION_MASK)
|
||||
if (raw_cpu_read(lockdep_recursion))
|
||||
return false;
|
||||
|
||||
if (!in_nmi())
|
||||
@@ -5369,7 +5412,10 @@ void lock_acquire(struct lockdep_map *lock, unsigned int subclass,
|
||||
|
||||
trace_lock_acquire(lock, subclass, trylock, read, check, nest_lock, ip);
|
||||
|
||||
if (unlikely(current->lockdep_recursion)) {
|
||||
if (!debug_locks)
|
||||
return;
|
||||
|
||||
if (unlikely(!lockdep_enabled())) {
|
||||
/* XXX allow trylock from NMI ?!? */
|
||||
if (lockdep_nmi() && !trylock) {
|
||||
struct held_lock hlock;
|
||||
@@ -5392,7 +5438,7 @@ void lock_acquire(struct lockdep_map *lock, unsigned int subclass,
|
||||
raw_local_irq_save(flags);
|
||||
check_flags(flags);
|
||||
|
||||
current->lockdep_recursion++;
|
||||
lockdep_recursion_inc();
|
||||
__lock_acquire(lock, subclass, trylock, read, check,
|
||||
irqs_disabled_flags(flags), nest_lock, ip, 0, 0);
|
||||
lockdep_recursion_finish();
|
||||
@@ -5406,13 +5452,13 @@ void lock_release(struct lockdep_map *lock, unsigned long ip)
|
||||
|
||||
trace_lock_release(lock, ip);
|
||||
|
||||
if (unlikely(current->lockdep_recursion))
|
||||
if (unlikely(!lockdep_enabled()))
|
||||
return;
|
||||
|
||||
raw_local_irq_save(flags);
|
||||
check_flags(flags);
|
||||
|
||||
current->lockdep_recursion++;
|
||||
lockdep_recursion_inc();
|
||||
if (__lock_release(lock, ip))
|
||||
check_chain_key(current);
|
||||
lockdep_recursion_finish();
|
||||
@@ -5425,13 +5471,13 @@ noinstr int lock_is_held_type(const struct lockdep_map *lock, int read)
|
||||
unsigned long flags;
|
||||
int ret = 0;
|
||||
|
||||
if (unlikely(current->lockdep_recursion))
|
||||
if (unlikely(!lockdep_enabled()))
|
||||
return 1; /* avoid false negative lockdep_assert_held() */
|
||||
|
||||
raw_local_irq_save(flags);
|
||||
check_flags(flags);
|
||||
|
||||
current->lockdep_recursion++;
|
||||
lockdep_recursion_inc();
|
||||
ret = __lock_is_held(lock, read);
|
||||
lockdep_recursion_finish();
|
||||
raw_local_irq_restore(flags);
|
||||
@@ -5446,13 +5492,13 @@ struct pin_cookie lock_pin_lock(struct lockdep_map *lock)
|
||||
struct pin_cookie cookie = NIL_COOKIE;
|
||||
unsigned long flags;
|
||||
|
||||
if (unlikely(current->lockdep_recursion))
|
||||
if (unlikely(!lockdep_enabled()))
|
||||
return cookie;
|
||||
|
||||
raw_local_irq_save(flags);
|
||||
check_flags(flags);
|
||||
|
||||
current->lockdep_recursion++;
|
||||
lockdep_recursion_inc();
|
||||
cookie = __lock_pin_lock(lock);
|
||||
lockdep_recursion_finish();
|
||||
raw_local_irq_restore(flags);
|
||||
@@ -5465,13 +5511,13 @@ void lock_repin_lock(struct lockdep_map *lock, struct pin_cookie cookie)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
if (unlikely(current->lockdep_recursion))
|
||||
if (unlikely(!lockdep_enabled()))
|
||||
return;
|
||||
|
||||
raw_local_irq_save(flags);
|
||||
check_flags(flags);
|
||||
|
||||
current->lockdep_recursion++;
|
||||
lockdep_recursion_inc();
|
||||
__lock_repin_lock(lock, cookie);
|
||||
lockdep_recursion_finish();
|
||||
raw_local_irq_restore(flags);
|
||||
@@ -5482,13 +5528,13 @@ void lock_unpin_lock(struct lockdep_map *lock, struct pin_cookie cookie)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
if (unlikely(current->lockdep_recursion))
|
||||
if (unlikely(!lockdep_enabled()))
|
||||
return;
|
||||
|
||||
raw_local_irq_save(flags);
|
||||
check_flags(flags);
|
||||
|
||||
current->lockdep_recursion++;
|
||||
lockdep_recursion_inc();
|
||||
__lock_unpin_lock(lock, cookie);
|
||||
lockdep_recursion_finish();
|
||||
raw_local_irq_restore(flags);
|
||||
@@ -5618,15 +5664,12 @@ void lock_contended(struct lockdep_map *lock, unsigned long ip)
|
||||
|
||||
trace_lock_acquired(lock, ip);
|
||||
|
||||
if (unlikely(!lock_stat || !debug_locks))
|
||||
return;
|
||||
|
||||
if (unlikely(current->lockdep_recursion))
|
||||
if (unlikely(!lock_stat || !lockdep_enabled()))
|
||||
return;
|
||||
|
||||
raw_local_irq_save(flags);
|
||||
check_flags(flags);
|
||||
current->lockdep_recursion++;
|
||||
lockdep_recursion_inc();
|
||||
__lock_contended(lock, ip);
|
||||
lockdep_recursion_finish();
|
||||
raw_local_irq_restore(flags);
|
||||
@@ -5639,15 +5682,12 @@ void lock_acquired(struct lockdep_map *lock, unsigned long ip)
|
||||
|
||||
trace_lock_contended(lock, ip);
|
||||
|
||||
if (unlikely(!lock_stat || !debug_locks))
|
||||
return;
|
||||
|
||||
if (unlikely(current->lockdep_recursion))
|
||||
if (unlikely(!lock_stat || !lockdep_enabled()))
|
||||
return;
|
||||
|
||||
raw_local_irq_save(flags);
|
||||
check_flags(flags);
|
||||
current->lockdep_recursion++;
|
||||
lockdep_recursion_inc();
|
||||
__lock_acquired(lock, ip);
|
||||
lockdep_recursion_finish();
|
||||
raw_local_irq_restore(flags);
|
||||
|
||||
@@ -19,9 +19,13 @@ enum lock_usage_bit {
|
||||
#include "lockdep_states.h"
|
||||
#undef LOCKDEP_STATE
|
||||
LOCK_USED,
|
||||
LOCK_USAGE_STATES
|
||||
LOCK_USED_READ,
|
||||
LOCK_USAGE_STATES,
|
||||
};
|
||||
|
||||
/* states after LOCK_USED_READ are not traced and printed */
|
||||
static_assert(LOCK_TRACE_STATES == LOCK_USAGE_STATES);
|
||||
|
||||
#define LOCK_USAGE_READ_MASK 1
|
||||
#define LOCK_USAGE_DIR_MASK 2
|
||||
#define LOCK_USAGE_STATE_MASK (~(LOCK_USAGE_READ_MASK | LOCK_USAGE_DIR_MASK))
|
||||
@@ -40,6 +44,7 @@ enum {
|
||||
#include "lockdep_states.h"
|
||||
#undef LOCKDEP_STATE
|
||||
__LOCKF(USED)
|
||||
__LOCKF(USED_READ)
|
||||
};
|
||||
|
||||
#define LOCKDEP_STATE(__STATE) LOCKF_ENABLED_##__STATE |
|
||||
@@ -119,7 +124,7 @@ static const unsigned long LOCKF_USED_IN_IRQ_READ =
|
||||
extern struct list_head all_lock_classes;
|
||||
extern struct lock_chain lock_chains[];
|
||||
|
||||
#define LOCK_USAGE_CHARS (1+LOCK_USAGE_STATES/2)
|
||||
#define LOCK_USAGE_CHARS (2*XXX_LOCK_USAGE_STATES + 1)
|
||||
|
||||
extern void get_usage_chars(struct lock_class *class,
|
||||
char usage[LOCK_USAGE_CHARS]);
|
||||
|
||||
@@ -45,7 +45,7 @@ EXPORT_SYMBOL_GPL(percpu_free_rwsem);
|
||||
|
||||
static bool __percpu_down_read_trylock(struct percpu_rw_semaphore *sem)
|
||||
{
|
||||
__this_cpu_inc(*sem->read_count);
|
||||
this_cpu_inc(*sem->read_count);
|
||||
|
||||
/*
|
||||
* Due to having preemption disabled the decrement happens on
|
||||
@@ -71,7 +71,7 @@ static bool __percpu_down_read_trylock(struct percpu_rw_semaphore *sem)
|
||||
if (likely(!atomic_read_acquire(&sem->block)))
|
||||
return true;
|
||||
|
||||
__this_cpu_dec(*sem->read_count);
|
||||
this_cpu_dec(*sem->read_count);
|
||||
|
||||
/* Prod writer to re-evaluate readers_active_check() */
|
||||
rcuwait_wake_up(&sem->writer);
|
||||
|
||||
+3
-2
@@ -215,12 +215,13 @@ int padata_do_parallel(struct padata_shell *ps,
|
||||
padata->pd = pd;
|
||||
padata->cb_cpu = *cb_cpu;
|
||||
|
||||
rcu_read_unlock_bh();
|
||||
|
||||
spin_lock(&padata_works_lock);
|
||||
padata->seq_nr = ++pd->seq_nr;
|
||||
pw = padata_work_alloc();
|
||||
spin_unlock(&padata_works_lock);
|
||||
|
||||
rcu_read_unlock_bh();
|
||||
|
||||
if (pw) {
|
||||
padata_work_init(pw, padata_parallel_worker, padata, 0);
|
||||
queue_work(pinst->parallel_wq, &pw->pw_work);
|
||||
|
||||
@@ -659,7 +659,7 @@ static void power_down(void)
|
||||
break;
|
||||
case HIBERNATION_PLATFORM:
|
||||
hibernation_platform_enter();
|
||||
/* Fall through */
|
||||
fallthrough;
|
||||
case HIBERNATION_SHUTDOWN:
|
||||
if (pm_power_off)
|
||||
kernel_power_off();
|
||||
|
||||
+2
-2
@@ -119,7 +119,7 @@ int pm_qos_update_target(struct pm_qos_constraints *c, struct plist_node *node,
|
||||
* and add, then see if the aggregate has changed.
|
||||
*/
|
||||
plist_del(node, &c->list);
|
||||
/* fall through */
|
||||
fallthrough;
|
||||
case PM_QOS_ADD_REQ:
|
||||
plist_node_init(node, new_value);
|
||||
plist_add(node, &c->list);
|
||||
@@ -188,7 +188,7 @@ bool pm_qos_update_flags(struct pm_qos_flags *pqf,
|
||||
break;
|
||||
case PM_QOS_UPDATE_REQ:
|
||||
pm_qos_flags_remove_req(pqf, req);
|
||||
/* fall through */
|
||||
fallthrough;
|
||||
case PM_QOS_ADD_REQ:
|
||||
req->flags = val;
|
||||
INIT_LIST_HEAD(&req->node);
|
||||
|
||||
+1
-1
@@ -590,7 +590,7 @@ void exit_tasks_rcu_finish(void) __releases(&tasks_rcu_exit_srcu)
|
||||
}
|
||||
|
||||
#else /* #ifdef CONFIG_TASKS_RCU */
|
||||
static void show_rcu_tasks_classic_gp_kthread(void) { }
|
||||
static inline void show_rcu_tasks_classic_gp_kthread(void) { }
|
||||
void exit_tasks_rcu_start(void) { }
|
||||
void exit_tasks_rcu_finish(void) { exit_tasks_rcu_finish_trace(current); }
|
||||
#endif /* #else #ifdef CONFIG_TASKS_RCU */
|
||||
|
||||
@@ -673,6 +673,7 @@ void rcu_idle_enter(void)
|
||||
lockdep_assert_irqs_disabled();
|
||||
rcu_eqs_enter(false);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rcu_idle_enter);
|
||||
|
||||
#ifdef CONFIG_NO_HZ_FULL
|
||||
/**
|
||||
@@ -886,6 +887,7 @@ void rcu_idle_exit(void)
|
||||
rcu_eqs_exit(false);
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rcu_idle_exit);
|
||||
|
||||
#ifdef CONFIG_NO_HZ_FULL
|
||||
/**
|
||||
|
||||
+1
-1
@@ -2320,7 +2320,7 @@ static int select_fallback_rq(int cpu, struct task_struct *p)
|
||||
state = possible;
|
||||
break;
|
||||
}
|
||||
/* Fall-through */
|
||||
fallthrough;
|
||||
case possible:
|
||||
do_set_cpus_allowed(p, cpu_possible_mask);
|
||||
state = fail;
|
||||
|
||||
@@ -1219,13 +1219,13 @@ static void __free_domain_allocs(struct s_data *d, enum s_alloc what,
|
||||
case sa_rootdomain:
|
||||
if (!atomic_read(&d->rd->refcount))
|
||||
free_rootdomain(&d->rd->rcu);
|
||||
/* Fall through */
|
||||
fallthrough;
|
||||
case sa_sd:
|
||||
free_percpu(d->sd);
|
||||
/* Fall through */
|
||||
fallthrough;
|
||||
case sa_sd_storage:
|
||||
__sdt_free(cpu_map);
|
||||
/* Fall through */
|
||||
fallthrough;
|
||||
case sa_none:
|
||||
break;
|
||||
}
|
||||
|
||||
+18
-6
@@ -1109,13 +1109,18 @@ out:
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SECCOMP_FILTER
|
||||
static int seccomp_notify_release(struct inode *inode, struct file *file)
|
||||
static void seccomp_notify_free(struct seccomp_filter *filter)
|
||||
{
|
||||
kfree(filter->notif);
|
||||
filter->notif = NULL;
|
||||
}
|
||||
|
||||
static void seccomp_notify_detach(struct seccomp_filter *filter)
|
||||
{
|
||||
struct seccomp_filter *filter = file->private_data;
|
||||
struct seccomp_knotif *knotif;
|
||||
|
||||
if (!filter)
|
||||
return 0;
|
||||
return;
|
||||
|
||||
mutex_lock(&filter->notify_lock);
|
||||
|
||||
@@ -1139,9 +1144,15 @@ static int seccomp_notify_release(struct inode *inode, struct file *file)
|
||||
complete(&knotif->ready);
|
||||
}
|
||||
|
||||
kfree(filter->notif);
|
||||
filter->notif = NULL;
|
||||
seccomp_notify_free(filter);
|
||||
mutex_unlock(&filter->notify_lock);
|
||||
}
|
||||
|
||||
static int seccomp_notify_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct seccomp_filter *filter = file->private_data;
|
||||
|
||||
seccomp_notify_detach(filter);
|
||||
__put_seccomp_filter(filter);
|
||||
return 0;
|
||||
}
|
||||
@@ -1488,7 +1499,7 @@ static struct file *init_listener(struct seccomp_filter *filter)
|
||||
|
||||
out_notif:
|
||||
if (IS_ERR(ret))
|
||||
kfree(filter->notif);
|
||||
seccomp_notify_free(filter);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
@@ -1581,6 +1592,7 @@ out_put_fd:
|
||||
listener_f->private_data = NULL;
|
||||
fput(listener_f);
|
||||
put_unused_fd(listener);
|
||||
seccomp_notify_detach(prepared);
|
||||
} else {
|
||||
fd_install(listener, listener_f);
|
||||
ret = listener;
|
||||
|
||||
+1
-1
@@ -851,7 +851,7 @@ static int check_kill_permission(int sig, struct kernel_siginfo *info,
|
||||
*/
|
||||
if (!sid || sid == task_session(current))
|
||||
break;
|
||||
/* fall through */
|
||||
fallthrough;
|
||||
default:
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@
|
||||
static DEFINE_STATIC_KEY_FALSE(stack_erasing_bypass);
|
||||
|
||||
int stack_erasing_sysctl(struct ctl_table *table, int write,
|
||||
void __user *buffer, size_t *lenp, loff_t *ppos)
|
||||
void *buffer, size_t *lenp, loff_t *ppos)
|
||||
{
|
||||
int ret = 0;
|
||||
int state = !static_branch_unlikely(&stack_erasing_bypass);
|
||||
|
||||
+1
-1
@@ -1753,7 +1753,7 @@ void getrusage(struct task_struct *p, int who, struct rusage *r)
|
||||
|
||||
if (who == RUSAGE_CHILDREN)
|
||||
break;
|
||||
/* fall through */
|
||||
fallthrough;
|
||||
|
||||
case RUSAGE_SELF:
|
||||
thread_group_cputime_adjusted(p, &tgutime, &tgstime);
|
||||
|
||||
+9
-2
@@ -204,8 +204,7 @@ static int max_extfrag_threshold = 1000;
|
||||
|
||||
#if defined(CONFIG_BPF_SYSCALL) && defined(CONFIG_SYSCTL)
|
||||
static int bpf_stats_handler(struct ctl_table *table, int write,
|
||||
void __user *buffer, size_t *lenp,
|
||||
loff_t *ppos)
|
||||
void *buffer, size_t *lenp, loff_t *ppos)
|
||||
{
|
||||
struct static_key *key = (struct static_key *)table->data;
|
||||
static int saved_val;
|
||||
@@ -2913,6 +2912,14 @@ static struct ctl_table vm_table[] = {
|
||||
.proc_handler = percpu_pagelist_fraction_sysctl_handler,
|
||||
.extra1 = SYSCTL_ZERO,
|
||||
},
|
||||
{
|
||||
.procname = "page_lock_unfairness",
|
||||
.data = &sysctl_page_lock_unfairness,
|
||||
.maxlen = sizeof(sysctl_page_lock_unfairness),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec_minmax,
|
||||
.extra1 = SYSCTL_ZERO,
|
||||
},
|
||||
#ifdef CONFIG_MMU
|
||||
{
|
||||
.procname = "max_map_count",
|
||||
|
||||
@@ -377,7 +377,7 @@ static bool hrtimer_fixup_activate(void *addr, enum debug_obj_state state)
|
||||
switch (state) {
|
||||
case ODEBUG_STATE_ACTIVE:
|
||||
WARN_ON(1);
|
||||
/* fall through */
|
||||
fallthrough;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -439,12 +439,12 @@ static struct pid *good_sigevent(sigevent_t * event)
|
||||
rtn = pid_task(pid, PIDTYPE_PID);
|
||||
if (!rtn || !same_thread_group(rtn, current))
|
||||
return NULL;
|
||||
/* FALLTHRU */
|
||||
fallthrough;
|
||||
case SIGEV_SIGNAL:
|
||||
case SIGEV_THREAD:
|
||||
if (event->sigev_signo <= 0 || event->sigev_signo > SIGRTMAX)
|
||||
return NULL;
|
||||
/* FALLTHRU */
|
||||
fallthrough;
|
||||
case SIGEV_NONE:
|
||||
return pid;
|
||||
default:
|
||||
|
||||
@@ -381,7 +381,7 @@ void tick_broadcast_control(enum tick_broadcast_mode mode)
|
||||
switch (mode) {
|
||||
case TICK_BROADCAST_FORCE:
|
||||
tick_broadcast_forced = 1;
|
||||
/* fall through */
|
||||
fallthrough;
|
||||
case TICK_BROADCAST_ON:
|
||||
cpumask_set_cpu(cpu, tick_broadcast_on);
|
||||
if (!cpumask_test_and_set_cpu(cpu, tick_broadcast_mask)) {
|
||||
|
||||
+1
-1
@@ -666,7 +666,7 @@ static bool timer_fixup_activate(void *addr, enum debug_obj_state state)
|
||||
|
||||
case ODEBUG_STATE_ACTIVE:
|
||||
WARN_ON(1);
|
||||
/* fall through */
|
||||
fallthrough;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -745,7 +745,7 @@ int blk_trace_ioctl(struct block_device *bdev, unsigned cmd, char __user *arg)
|
||||
#endif
|
||||
case BLKTRACESTART:
|
||||
start = 1;
|
||||
/* fall through */
|
||||
fallthrough;
|
||||
case BLKTRACESTOP:
|
||||
ret = __blk_trace_startstop(q, start);
|
||||
break;
|
||||
|
||||
@@ -2782,6 +2782,7 @@ static void ftrace_remove_trampoline_from_kallsyms(struct ftrace_ops *ops)
|
||||
{
|
||||
lockdep_assert_held(&ftrace_lock);
|
||||
list_del_rcu(&ops->list);
|
||||
synchronize_rcu();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2862,6 +2863,8 @@ int ftrace_startup(struct ftrace_ops *ops, int command)
|
||||
__unregister_ftrace_function(ops);
|
||||
ftrace_start_up--;
|
||||
ops->flags &= ~FTRACE_OPS_FL_ENABLED;
|
||||
if (ops->flags & FTRACE_OPS_FL_DYNAMIC)
|
||||
ftrace_trampoline_free(ops);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -6990,16 +6993,14 @@ static void ftrace_ops_assist_func(unsigned long ip, unsigned long parent_ip,
|
||||
{
|
||||
int bit;
|
||||
|
||||
if ((op->flags & FTRACE_OPS_FL_RCU) && !rcu_is_watching())
|
||||
return;
|
||||
|
||||
bit = trace_test_and_set_recursion(TRACE_LIST_START, TRACE_LIST_MAX);
|
||||
if (bit < 0)
|
||||
return;
|
||||
|
||||
preempt_disable_notrace();
|
||||
|
||||
op->func(ip, parent_ip, op, regs);
|
||||
if (!(op->flags & FTRACE_OPS_FL_RCU) || rcu_is_watching())
|
||||
op->func(ip, parent_ip, op, regs);
|
||||
|
||||
preempt_enable_notrace();
|
||||
trace_clear_recursion(bit);
|
||||
@@ -7531,8 +7532,7 @@ static bool is_permanent_ops_registered(void)
|
||||
|
||||
int
|
||||
ftrace_enable_sysctl(struct ctl_table *table, int write,
|
||||
void __user *buffer, size_t *lenp,
|
||||
loff_t *ppos)
|
||||
void *buffer, size_t *lenp, loff_t *ppos)
|
||||
{
|
||||
int ret = -ENODEV;
|
||||
|
||||
|
||||
+25
-23
@@ -3546,13 +3546,15 @@ struct trace_entry *trace_find_next_entry(struct trace_iterator *iter,
|
||||
if (iter->ent && iter->ent != iter->temp) {
|
||||
if ((!iter->temp || iter->temp_size < iter->ent_size) &&
|
||||
!WARN_ON_ONCE(iter->temp == static_temp_buf)) {
|
||||
kfree(iter->temp);
|
||||
iter->temp = kmalloc(iter->ent_size, GFP_KERNEL);
|
||||
if (!iter->temp)
|
||||
void *temp;
|
||||
temp = kmalloc(iter->ent_size, GFP_KERNEL);
|
||||
if (!temp)
|
||||
return NULL;
|
||||
kfree(iter->temp);
|
||||
iter->temp = temp;
|
||||
iter->temp_size = iter->ent_size;
|
||||
}
|
||||
memcpy(iter->temp, iter->ent, iter->ent_size);
|
||||
iter->temp_size = iter->ent_size;
|
||||
iter->ent = iter->temp;
|
||||
}
|
||||
entry = __find_next_entry(iter, ent_cpu, NULL, ent_ts);
|
||||
@@ -3782,14 +3784,14 @@ unsigned long trace_total_entries(struct trace_array *tr)
|
||||
|
||||
static void print_lat_help_header(struct seq_file *m)
|
||||
{
|
||||
seq_puts(m, "# _------=> CPU# \n"
|
||||
"# / _-----=> irqs-off \n"
|
||||
"# | / _----=> need-resched \n"
|
||||
"# || / _---=> hardirq/softirq \n"
|
||||
"# ||| / _--=> preempt-depth \n"
|
||||
"# |||| / delay \n"
|
||||
"# cmd pid ||||| time | caller \n"
|
||||
"# \\ / ||||| \\ | / \n");
|
||||
seq_puts(m, "# _------=> CPU# \n"
|
||||
"# / _-----=> irqs-off \n"
|
||||
"# | / _----=> need-resched \n"
|
||||
"# || / _---=> hardirq/softirq \n"
|
||||
"# ||| / _--=> preempt-depth \n"
|
||||
"# |||| / delay \n"
|
||||
"# cmd pid ||||| time | caller \n"
|
||||
"# \\ / ||||| \\ | / \n");
|
||||
}
|
||||
|
||||
static void print_event_info(struct array_buffer *buf, struct seq_file *m)
|
||||
@@ -3810,26 +3812,26 @@ static void print_func_help_header(struct array_buffer *buf, struct seq_file *m,
|
||||
|
||||
print_event_info(buf, m);
|
||||
|
||||
seq_printf(m, "# TASK-PID %s CPU# TIMESTAMP FUNCTION\n", tgid ? "TGID " : "");
|
||||
seq_printf(m, "# | | %s | | |\n", tgid ? " | " : "");
|
||||
seq_printf(m, "# TASK-PID %s CPU# TIMESTAMP FUNCTION\n", tgid ? " TGID " : "");
|
||||
seq_printf(m, "# | | %s | | |\n", tgid ? " | " : "");
|
||||
}
|
||||
|
||||
static void print_func_help_header_irq(struct array_buffer *buf, struct seq_file *m,
|
||||
unsigned int flags)
|
||||
{
|
||||
bool tgid = flags & TRACE_ITER_RECORD_TGID;
|
||||
const char *space = " ";
|
||||
int prec = tgid ? 10 : 2;
|
||||
const char *space = " ";
|
||||
int prec = tgid ? 12 : 2;
|
||||
|
||||
print_event_info(buf, m);
|
||||
|
||||
seq_printf(m, "# %.*s _-----=> irqs-off\n", prec, space);
|
||||
seq_printf(m, "# %.*s / _----=> need-resched\n", prec, space);
|
||||
seq_printf(m, "# %.*s| / _---=> hardirq/softirq\n", prec, space);
|
||||
seq_printf(m, "# %.*s|| / _--=> preempt-depth\n", prec, space);
|
||||
seq_printf(m, "# %.*s||| / delay\n", prec, space);
|
||||
seq_printf(m, "# TASK-PID %.*sCPU# |||| TIMESTAMP FUNCTION\n", prec, " TGID ");
|
||||
seq_printf(m, "# | | %.*s | |||| | |\n", prec, " | ");
|
||||
seq_printf(m, "# %.*s _-----=> irqs-off\n", prec, space);
|
||||
seq_printf(m, "# %.*s / _----=> need-resched\n", prec, space);
|
||||
seq_printf(m, "# %.*s| / _---=> hardirq/softirq\n", prec, space);
|
||||
seq_printf(m, "# %.*s|| / _--=> preempt-depth\n", prec, space);
|
||||
seq_printf(m, "# %.*s||| / delay\n", prec, space);
|
||||
seq_printf(m, "# TASK-PID %.*s CPU# |||| TIMESTAMP FUNCTION\n", prec, " TGID ");
|
||||
seq_printf(m, "# | | %.*s | |||| | |\n", prec, " | ");
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -499,7 +499,7 @@ predicate_parse(const char *str, int nr_parens, int nr_preds,
|
||||
ptr++;
|
||||
break;
|
||||
}
|
||||
/* fall through */
|
||||
fallthrough;
|
||||
default:
|
||||
parse_error(pe, FILT_ERR_TOO_MANY_PREDS,
|
||||
next - str);
|
||||
@@ -1273,7 +1273,7 @@ static int parse_pred(const char *str, void *data,
|
||||
switch (op) {
|
||||
case OP_NE:
|
||||
pred->not = 1;
|
||||
/* Fall through */
|
||||
fallthrough;
|
||||
case OP_GLOB:
|
||||
case OP_EQ:
|
||||
break;
|
||||
|
||||
@@ -3865,7 +3865,6 @@ static int parse_var_defs(struct hist_trigger_data *hist_data)
|
||||
|
||||
s = kstrdup(field_str, GFP_KERNEL);
|
||||
if (!s) {
|
||||
kfree(hist_data->attrs->var_defs.name[n_vars]);
|
||||
ret = -ENOMEM;
|
||||
goto free;
|
||||
}
|
||||
|
||||
@@ -497,7 +497,7 @@ lat_print_generic(struct trace_seq *s, struct trace_entry *entry, int cpu)
|
||||
|
||||
trace_find_cmdline(entry->pid, comm);
|
||||
|
||||
trace_seq_printf(s, "%8.8s-%-5d %3d",
|
||||
trace_seq_printf(s, "%8.8s-%-7d %3d",
|
||||
comm, entry->pid, cpu);
|
||||
|
||||
return trace_print_lat_fmt(s, entry);
|
||||
@@ -588,15 +588,15 @@ int trace_print_context(struct trace_iterator *iter)
|
||||
|
||||
trace_find_cmdline(entry->pid, comm);
|
||||
|
||||
trace_seq_printf(s, "%16s-%-5d ", comm, entry->pid);
|
||||
trace_seq_printf(s, "%16s-%-7d ", comm, entry->pid);
|
||||
|
||||
if (tr->trace_flags & TRACE_ITER_RECORD_TGID) {
|
||||
unsigned int tgid = trace_find_tgid(entry->pid);
|
||||
|
||||
if (!tgid)
|
||||
trace_seq_printf(s, "(-----) ");
|
||||
trace_seq_printf(s, "(-------) ");
|
||||
else
|
||||
trace_seq_printf(s, "(%5d) ", tgid);
|
||||
trace_seq_printf(s, "(%7d) ", tgid);
|
||||
}
|
||||
|
||||
trace_seq_printf(s, "[%03d] ", iter->cpu);
|
||||
@@ -636,7 +636,7 @@ int trace_print_lat_context(struct trace_iterator *iter)
|
||||
trace_find_cmdline(entry->pid, comm);
|
||||
|
||||
trace_seq_printf(
|
||||
s, "%16s %5d %3d %d %08x %08lx ",
|
||||
s, "%16s %7d %3d %d %08x %08lx ",
|
||||
comm, entry->pid, iter->cpu, entry->flags,
|
||||
entry->preempt_count, iter->idx);
|
||||
} else {
|
||||
@@ -917,7 +917,7 @@ static enum print_line_t trace_ctxwake_print(struct trace_iterator *iter,
|
||||
S = task_index_to_char(field->prev_state);
|
||||
trace_find_cmdline(field->next_pid, comm);
|
||||
trace_seq_printf(&iter->seq,
|
||||
" %5d:%3d:%c %s [%03d] %5d:%3d:%c %s\n",
|
||||
" %7d:%3d:%c %s [%03d] %7d:%3d:%c %s\n",
|
||||
field->prev_pid,
|
||||
field->prev_prio,
|
||||
S, delim,
|
||||
|
||||
@@ -102,14 +102,14 @@ NOKPROBE_SYMBOL(trace_hardirqs_on_caller);
|
||||
|
||||
__visible void trace_hardirqs_off_caller(unsigned long caller_addr)
|
||||
{
|
||||
lockdep_hardirqs_off(CALLER_ADDR0);
|
||||
|
||||
if (!this_cpu_read(tracing_irq_cpu)) {
|
||||
this_cpu_write(tracing_irq_cpu, 1);
|
||||
tracer_hardirqs_off(CALLER_ADDR0, caller_addr);
|
||||
if (!in_nmi())
|
||||
trace_irq_disable_rcuidle(CALLER_ADDR0, caller_addr);
|
||||
}
|
||||
|
||||
lockdep_hardirqs_off(CALLER_ADDR0);
|
||||
}
|
||||
EXPORT_SYMBOL(trace_hardirqs_off_caller);
|
||||
NOKPROBE_SYMBOL(trace_hardirqs_off_caller);
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <linux/cred.h>
|
||||
#include <linux/file.h>
|
||||
#include <linux/fdtable.h>
|
||||
#include <linux/fs_struct.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/security.h>
|
||||
#include <linux/mount.h>
|
||||
@@ -71,6 +72,14 @@ static int call_usermodehelper_exec_async(void *data)
|
||||
flush_signal_handlers(current, 1);
|
||||
spin_unlock_irq(¤t->sighand->siglock);
|
||||
|
||||
/*
|
||||
* Initial kernel threads share ther FS with init, in order to
|
||||
* get the init root directory. But we've now created a new
|
||||
* thread that is going to execve a user process and has its own
|
||||
* 'struct fs_struct'. Reset umask to the default.
|
||||
*/
|
||||
current->fs->umask = 0022;
|
||||
|
||||
/*
|
||||
* Our parent (unbound workqueue) runs with elevated scheduling
|
||||
* priority. Avoid propagating that into the userspace child.
|
||||
|
||||
Reference in New Issue
Block a user