diff options
| author | Michael Bestas <mkbestas@lineageos.org> | 2020-11-15 21:52:06 +0200 |
|---|---|---|
| committer | Michael Bestas <mkbestas@lineageos.org> | 2020-11-15 21:52:18 +0200 |
| commit | 6107aa6dc24cc8c196bb18e5b5ec81f8f1a275a8 (patch) | |
| tree | ef508ed8340c5d6b615c713d1569d851964091f2 /kernel | |
| parent | 298504ed68065a61d0fc1d7969af19ecf2136ac9 (diff) | |
| parent | 34b1d1174c2c7054c01cfa39d274421d80649386 (diff) | |
Merge branch 'android-4.4-p' of https://android.googlesource.com/kernel/common into lineage-17.1-caf-msm8998
This brings LA.UM.8.2.r1-07400-sdm660.0 up to date with
https://android.googlesource.com/kernel/common/ android-4.4-p at commit:
34b1d1174c2c7 UPSTREAM: arm64: kaslr: Fix up the kernel image alignment
Conflicts:
scripts/setlocalversion
Change-Id: Id2981587a6e92eb10cfdc9b6d13cd4bd2abb5670
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/debug/debug_core.c | 22 | ||||
| -rw-r--r-- | kernel/debug/kdb/kdb_io.c | 8 | ||||
| -rw-r--r-- | kernel/fork.c | 10 | ||||
| -rw-r--r-- | kernel/power/hibernate.c | 11 | ||||
| -rw-r--r-- | kernel/sched/fair.c | 39 | ||||
| -rw-r--r-- | kernel/trace/ring_buffer.c | 8 | ||||
| -rw-r--r-- | kernel/trace/trace.h | 26 | ||||
| -rw-r--r-- | kernel/trace/trace_selftest.c | 9 |
8 files changed, 95 insertions, 38 deletions
diff --git a/kernel/debug/debug_core.c b/kernel/debug/debug_core.c index 321ccdbb7364..bc791cec58e6 100644 --- a/kernel/debug/debug_core.c +++ b/kernel/debug/debug_core.c @@ -94,14 +94,6 @@ int dbg_switch_cpu; /* Use kdb or gdbserver mode */ int dbg_kdb_mode = 1; -static int __init opt_kgdb_con(char *str) -{ - kgdb_use_con = 1; - return 0; -} - -early_param("kgdbcon", opt_kgdb_con); - module_param(kgdb_use_con, int, 0644); module_param(kgdbreboot, int, 0644); @@ -811,6 +803,20 @@ static struct console kgdbcons = { .index = -1, }; +static int __init opt_kgdb_con(char *str) +{ + kgdb_use_con = 1; + + if (kgdb_io_module_registered && !kgdb_con_registered) { + register_console(&kgdbcons); + kgdb_con_registered = 1; + } + + return 0; +} + +early_param("kgdbcon", opt_kgdb_con); + #ifdef CONFIG_MAGIC_SYSRQ static void sysrq_handle_dbg(int key) { diff --git a/kernel/debug/kdb/kdb_io.c b/kernel/debug/kdb/kdb_io.c index d3c5b15c86c1..4b537520432a 100644 --- a/kernel/debug/kdb/kdb_io.c +++ b/kernel/debug/kdb/kdb_io.c @@ -691,12 +691,16 @@ int vkdb_printf(enum kdb_msgsrc src, const char *fmt, va_list ap) size_avail = sizeof(kdb_buffer) - len; goto kdb_print_out; } - if (kdb_grepping_flag >= KDB_GREPPING_FLAG_SEARCH) + if (kdb_grepping_flag >= KDB_GREPPING_FLAG_SEARCH) { /* * This was a interactive search (using '/' at more - * prompt) and it has completed. Clear the flag. + * prompt) and it has completed. Replace the \0 with + * its original value to ensure multi-line strings + * are handled properly, and return to normal mode. */ + *cphold = replaced_byte; kdb_grepping_flag = 0; + } /* * at this point the string is a full line and * should be printed, up to the null. diff --git a/kernel/fork.c b/kernel/fork.c index 58514ce46152..7aa7dec289da 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -1574,14 +1574,9 @@ static struct task_struct *copy_process(unsigned long clone_flags, /* ok, now we should be set up.. */ p->pid = pid_nr(pid); if (clone_flags & CLONE_THREAD) { - p->exit_signal = -1; p->group_leader = current->group_leader; p->tgid = current->tgid; } else { - if (clone_flags & CLONE_PARENT) - p->exit_signal = current->group_leader->exit_signal; - else - p->exit_signal = (clone_flags & CSIGNAL); p->group_leader = p; p->tgid = p->pid; } @@ -1626,9 +1621,14 @@ static struct task_struct *copy_process(unsigned long clone_flags, if (clone_flags & (CLONE_PARENT|CLONE_THREAD)) { p->real_parent = current->real_parent; p->parent_exec_id = current->parent_exec_id; + if (clone_flags & CLONE_THREAD) + p->exit_signal = -1; + else + p->exit_signal = current->group_leader->exit_signal; } else { p->real_parent = current; p->parent_exec_id = current->self_exec_id; + p->exit_signal = (clone_flags & CSIGNAL); } spin_lock(¤t->sighand->siglock); diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c index 29771c69383b..184ea54e721a 100644 --- a/kernel/power/hibernate.c +++ b/kernel/power/hibernate.c @@ -784,17 +784,6 @@ static int software_resume(void) /* Check if the device is there */ swsusp_resume_device = name_to_dev_t(resume_file); - - /* - * name_to_dev_t is ineffective to verify parition if resume_file is in - * integer format. (e.g. major:minor) - */ - if (isdigit(resume_file[0]) && resume_wait) { - int partno; - while (!get_gendisk(swsusp_resume_device, &partno)) - msleep(10); - } - if (!swsusp_resume_device) { /* * Some device discovery might still be in progress; we need diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 29d80146eb8a..78bd960c3527 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -4179,6 +4179,36 @@ static inline int propagate_entity_load_avg(struct sched_entity *se) return 1; } +/* + * Check if we need to update the load and the utilization of a blocked + * group_entity: + */ +static inline bool skip_blocked_update(struct sched_entity *se) +{ + struct cfs_rq *gcfs_rq = group_cfs_rq(se); + + /* + * If sched_entity still have not zero load or utilization, we have to + * decay it: + */ + if (se->avg.load_avg || se->avg.util_avg) + return false; + + /* + * If there is a pending propagation, we have to update the load and + * the utilization of the sched_entity: + */ + if (gcfs_rq->propagate_avg) + return false; + + /* + * Otherwise, the load and the utilization of the sched_entity is + * already zero and there is no pending propagation, so it will be a + * waste of time to try to decay it: + */ + return true; +} + #else /* CONFIG_FAIR_GROUP_SCHED */ static inline void update_tg_load_avg(struct cfs_rq *cfs_rq, int force) {} @@ -9033,6 +9063,8 @@ static void update_blocked_averages(int cpu) * list_add_leaf_cfs_rq() for details. */ for_each_leaf_cfs_rq(rq, cfs_rq) { + struct sched_entity *se; + /* throttled entities do not contribute to load */ if (throttled_hierarchy(cfs_rq)) continue; @@ -9041,9 +9073,10 @@ static void update_blocked_averages(int cpu) true)) update_tg_load_avg(cfs_rq, 0); - /* Propagate pending load changes to the parent */ - if (cfs_rq->tg->se[cpu]) - update_load_avg(cfs_rq->tg->se[cpu], 0); + /* Propagate pending load changes to the parent, if any: */ + se = cfs_rq->tg->se[cpu]; + if (se && !skip_blocked_update(se)) + update_load_avg(se, 0); } raw_spin_unlock_irqrestore(&rq->lock, flags); } diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 1cf2402c6922..1c1ecc1d49ad 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -1659,18 +1659,18 @@ int ring_buffer_resize(struct ring_buffer *buffer, unsigned long size, { struct ring_buffer_per_cpu *cpu_buffer; unsigned long nr_pages; - int cpu, err = 0; + int cpu, err; /* * Always succeed at resizing a non-existent buffer: */ if (!buffer) - return size; + return 0; /* Make sure the requested buffer exists */ if (cpu_id != RING_BUFFER_ALL_CPUS && !cpumask_test_cpu(cpu_id, buffer->cpumask)) - return size; + return 0; nr_pages = DIV_ROUND_UP(size, BUF_PAGE_SIZE); @@ -1810,7 +1810,7 @@ int ring_buffer_resize(struct ring_buffer *buffer, unsigned long size, } mutex_unlock(&buffer->mutex); - return size; + return 0; out_err: for_each_buffer_cpu(buffer, cpu) { diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index f62768288592..6f9534635129 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -478,6 +478,12 @@ enum { * can only be modified by current, we can reuse trace_recursion. */ TRACE_IRQ_BIT, + + /* + * When transitioning between context, the preempt_count() may + * not be correct. Allow for a single recursion to cover this case. + */ + TRACE_TRANSITION_BIT, }; #define trace_recursion_set(bit) do { (current)->trace_recursion |= (1<<(bit)); } while (0) @@ -522,14 +528,27 @@ static __always_inline int trace_test_and_set_recursion(int start, int max) return 0; bit = trace_get_context_bit() + start; - if (unlikely(val & (1 << bit))) - return -1; + if (unlikely(val & (1 << bit))) { + /* + * It could be that preempt_count has not been updated during + * a switch between contexts. Allow for a single recursion. + */ + bit = TRACE_TRANSITION_BIT; + if (trace_recursion_test(bit)) + return -1; + trace_recursion_set(bit); + barrier(); + return bit + 1; + } + + /* Normal check passed, clear the transition to allow it again */ + trace_recursion_clear(TRACE_TRANSITION_BIT); val |= 1 << bit; current->trace_recursion = val; barrier(); - return bit; + return bit + 1; } static __always_inline void trace_clear_recursion(int bit) @@ -539,6 +558,7 @@ static __always_inline void trace_clear_recursion(int bit) if (!bit) return; + bit--; bit = 1 << bit; val &= ~bit; diff --git a/kernel/trace/trace_selftest.c b/kernel/trace/trace_selftest.c index ca70d11b8aa7..f444f57f1338 100644 --- a/kernel/trace/trace_selftest.c +++ b/kernel/trace/trace_selftest.c @@ -490,8 +490,13 @@ trace_selftest_function_recursion(void) unregister_ftrace_function(&test_rec_probe); ret = -1; - if (trace_selftest_recursion_cnt != 1) { - pr_cont("*callback not called once (%d)* ", + /* + * Recursion allows for transitions between context, + * and may call the callback twice. + */ + if (trace_selftest_recursion_cnt != 1 && + trace_selftest_recursion_cnt != 2) { + pr_cont("*callback not called once (or twice) (%d)* ", trace_selftest_recursion_cnt); goto out; } |
