Merge 4.0-rc5 into tty-next
We want the tty/serial fixes in here as well. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
+4
-5
@@ -548,9 +548,6 @@ static void update_domain_attr_tree(struct sched_domain_attr *dattr,
|
||||
|
||||
rcu_read_lock();
|
||||
cpuset_for_each_descendant_pre(cp, pos_css, root_cs) {
|
||||
if (cp == root_cs)
|
||||
continue;
|
||||
|
||||
/* skip the whole subtree if @cp doesn't have any CPU */
|
||||
if (cpumask_empty(cp->cpus_allowed)) {
|
||||
pos_css = css_rightmost_descendant(pos_css);
|
||||
@@ -873,7 +870,7 @@ static void update_cpumasks_hier(struct cpuset *cs, struct cpumask *new_cpus)
|
||||
* If it becomes empty, inherit the effective mask of the
|
||||
* parent, which is guaranteed to have some CPUs.
|
||||
*/
|
||||
if (cpumask_empty(new_cpus))
|
||||
if (cgroup_on_dfl(cp->css.cgroup) && cpumask_empty(new_cpus))
|
||||
cpumask_copy(new_cpus, parent->effective_cpus);
|
||||
|
||||
/* Skip the whole subtree if the cpumask remains the same. */
|
||||
@@ -1129,7 +1126,7 @@ static void update_nodemasks_hier(struct cpuset *cs, nodemask_t *new_mems)
|
||||
* If it becomes empty, inherit the effective mask of the
|
||||
* parent, which is guaranteed to have some MEMs.
|
||||
*/
|
||||
if (nodes_empty(*new_mems))
|
||||
if (cgroup_on_dfl(cp->css.cgroup) && nodes_empty(*new_mems))
|
||||
*new_mems = parent->effective_mems;
|
||||
|
||||
/* Skip the whole subtree if the nodemask remains the same. */
|
||||
@@ -1979,7 +1976,9 @@ static int cpuset_css_online(struct cgroup_subsys_state *css)
|
||||
|
||||
spin_lock_irq(&callback_lock);
|
||||
cs->mems_allowed = parent->mems_allowed;
|
||||
cs->effective_mems = parent->mems_allowed;
|
||||
cpumask_copy(cs->cpus_allowed, parent->cpus_allowed);
|
||||
cpumask_copy(cs->effective_cpus, parent->cpus_allowed);
|
||||
spin_unlock_irq(&callback_lock);
|
||||
out_unlock:
|
||||
mutex_unlock(&cpuset_mutex);
|
||||
|
||||
@@ -3591,7 +3591,7 @@ static void put_event(struct perf_event *event)
|
||||
ctx = perf_event_ctx_lock_nested(event, SINGLE_DEPTH_NESTING);
|
||||
WARN_ON_ONCE(ctx->parent_ctx);
|
||||
perf_remove_from_context(event, true);
|
||||
mutex_unlock(&ctx->mutex);
|
||||
perf_event_ctx_unlock(event, ctx);
|
||||
|
||||
_free_event(event);
|
||||
}
|
||||
|
||||
+26
-4
@@ -89,16 +89,28 @@ static bool klp_is_object_loaded(struct klp_object *obj)
|
||||
/* sets obj->mod if object is not vmlinux and module is found */
|
||||
static void klp_find_object_module(struct klp_object *obj)
|
||||
{
|
||||
struct module *mod;
|
||||
|
||||
if (!klp_is_module(obj))
|
||||
return;
|
||||
|
||||
mutex_lock(&module_mutex);
|
||||
/*
|
||||
* We don't need to take a reference on the module here because we have
|
||||
* the klp_mutex, which is also taken by the module notifier. This
|
||||
* prevents any module from unloading until we release the klp_mutex.
|
||||
* We do not want to block removal of patched modules and therefore
|
||||
* we do not take a reference here. The patches are removed by
|
||||
* a going module handler instead.
|
||||
*/
|
||||
obj->mod = find_module(obj->name);
|
||||
mod = find_module(obj->name);
|
||||
/*
|
||||
* Do not mess work of the module coming and going notifiers.
|
||||
* Note that the patch might still be needed before the going handler
|
||||
* is called. Module functions can be called even in the GOING state
|
||||
* until mod->exit() finishes. This is especially important for
|
||||
* patches that modify semantic of the functions.
|
||||
*/
|
||||
if (mod && mod->klp_alive)
|
||||
obj->mod = mod;
|
||||
|
||||
mutex_unlock(&module_mutex);
|
||||
}
|
||||
|
||||
@@ -767,6 +779,7 @@ static int klp_init_object(struct klp_patch *patch, struct klp_object *obj)
|
||||
return -EINVAL;
|
||||
|
||||
obj->state = KLP_DISABLED;
|
||||
obj->mod = NULL;
|
||||
|
||||
klp_find_object_module(obj);
|
||||
|
||||
@@ -961,6 +974,15 @@ static int klp_module_notify(struct notifier_block *nb, unsigned long action,
|
||||
|
||||
mutex_lock(&klp_mutex);
|
||||
|
||||
/*
|
||||
* Each module has to know that the notifier has been called.
|
||||
* We never know what module will get patched by a new patch.
|
||||
*/
|
||||
if (action == MODULE_STATE_COMING)
|
||||
mod->klp_alive = true;
|
||||
else /* MODULE_STATE_GOING */
|
||||
mod->klp_alive = false;
|
||||
|
||||
list_for_each_entry(patch, &klp_patches, list) {
|
||||
for (obj = patch->objs; obj->funcs; obj++) {
|
||||
if (!klp_is_module(obj) || strcmp(obj->name, mod->name))
|
||||
|
||||
@@ -56,7 +56,6 @@
|
||||
#include <linux/async.h>
|
||||
#include <linux/percpu.h>
|
||||
#include <linux/kmemleak.h>
|
||||
#include <linux/kasan.h>
|
||||
#include <linux/jump_label.h>
|
||||
#include <linux/pfn.h>
|
||||
#include <linux/bsearch.h>
|
||||
@@ -1814,7 +1813,6 @@ static void unset_module_init_ro_nx(struct module *mod) { }
|
||||
void __weak module_memfree(void *module_region)
|
||||
{
|
||||
vfree(module_region);
|
||||
kasan_module_free(module_region);
|
||||
}
|
||||
|
||||
void __weak module_arch_cleanup(struct module *mod)
|
||||
|
||||
+30
-10
@@ -1059,6 +1059,12 @@ static __init void ftrace_profile_debugfs(struct dentry *d_tracer)
|
||||
|
||||
static struct pid * const ftrace_swapper_pid = &init_struct_pid;
|
||||
|
||||
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
|
||||
static int ftrace_graph_active;
|
||||
#else
|
||||
# define ftrace_graph_active 0
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_DYNAMIC_FTRACE
|
||||
|
||||
static struct ftrace_ops *removed_ops;
|
||||
@@ -2041,8 +2047,12 @@ static int ftrace_check_record(struct dyn_ftrace *rec, int enable, int update)
|
||||
if (!ftrace_rec_count(rec))
|
||||
rec->flags = 0;
|
||||
else
|
||||
/* Just disable the record (keep REGS state) */
|
||||
rec->flags &= ~FTRACE_FL_ENABLED;
|
||||
/*
|
||||
* Just disable the record, but keep the ops TRAMP
|
||||
* and REGS states. The _EN flags must be disabled though.
|
||||
*/
|
||||
rec->flags &= ~(FTRACE_FL_ENABLED | FTRACE_FL_TRAMP_EN |
|
||||
FTRACE_FL_REGS_EN);
|
||||
}
|
||||
|
||||
return FTRACE_UPDATE_MAKE_NOP;
|
||||
@@ -2688,24 +2698,36 @@ static int ftrace_shutdown(struct ftrace_ops *ops, int command)
|
||||
|
||||
static void ftrace_startup_sysctl(void)
|
||||
{
|
||||
int command;
|
||||
|
||||
if (unlikely(ftrace_disabled))
|
||||
return;
|
||||
|
||||
/* Force update next time */
|
||||
saved_ftrace_func = NULL;
|
||||
/* ftrace_start_up is true if we want ftrace running */
|
||||
if (ftrace_start_up)
|
||||
ftrace_run_update_code(FTRACE_UPDATE_CALLS);
|
||||
if (ftrace_start_up) {
|
||||
command = FTRACE_UPDATE_CALLS;
|
||||
if (ftrace_graph_active)
|
||||
command |= FTRACE_START_FUNC_RET;
|
||||
ftrace_startup_enable(command);
|
||||
}
|
||||
}
|
||||
|
||||
static void ftrace_shutdown_sysctl(void)
|
||||
{
|
||||
int command;
|
||||
|
||||
if (unlikely(ftrace_disabled))
|
||||
return;
|
||||
|
||||
/* ftrace_start_up is true if ftrace is running */
|
||||
if (ftrace_start_up)
|
||||
ftrace_run_update_code(FTRACE_DISABLE_CALLS);
|
||||
if (ftrace_start_up) {
|
||||
command = FTRACE_DISABLE_CALLS;
|
||||
if (ftrace_graph_active)
|
||||
command |= FTRACE_STOP_FUNC_RET;
|
||||
ftrace_run_update_code(command);
|
||||
}
|
||||
}
|
||||
|
||||
static cycle_t ftrace_update_time;
|
||||
@@ -5558,12 +5580,12 @@ ftrace_enable_sysctl(struct ctl_table *table, int write,
|
||||
|
||||
if (ftrace_enabled) {
|
||||
|
||||
ftrace_startup_sysctl();
|
||||
|
||||
/* we are starting ftrace again */
|
||||
if (ftrace_ops_list != &ftrace_list_end)
|
||||
update_ftrace_function();
|
||||
|
||||
ftrace_startup_sysctl();
|
||||
|
||||
} else {
|
||||
/* stopping ftrace calls (just send to ftrace_stub) */
|
||||
ftrace_trace_function = ftrace_stub;
|
||||
@@ -5590,8 +5612,6 @@ static struct ftrace_ops graph_ops = {
|
||||
ASSIGN_OPS_HASH(graph_ops, &global_ops.local_hash)
|
||||
};
|
||||
|
||||
static int ftrace_graph_active;
|
||||
|
||||
int ftrace_graph_entry_stub(struct ftrace_graph_ent *trace)
|
||||
{
|
||||
return 0;
|
||||
|
||||
+52
-4
@@ -2728,19 +2728,57 @@ bool flush_work(struct work_struct *work)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(flush_work);
|
||||
|
||||
struct cwt_wait {
|
||||
wait_queue_t wait;
|
||||
struct work_struct *work;
|
||||
};
|
||||
|
||||
static int cwt_wakefn(wait_queue_t *wait, unsigned mode, int sync, void *key)
|
||||
{
|
||||
struct cwt_wait *cwait = container_of(wait, struct cwt_wait, wait);
|
||||
|
||||
if (cwait->work != key)
|
||||
return 0;
|
||||
return autoremove_wake_function(wait, mode, sync, key);
|
||||
}
|
||||
|
||||
static bool __cancel_work_timer(struct work_struct *work, bool is_dwork)
|
||||
{
|
||||
static DECLARE_WAIT_QUEUE_HEAD(cancel_waitq);
|
||||
unsigned long flags;
|
||||
int ret;
|
||||
|
||||
do {
|
||||
ret = try_to_grab_pending(work, is_dwork, &flags);
|
||||
/*
|
||||
* If someone else is canceling, wait for the same event it
|
||||
* would be waiting for before retrying.
|
||||
* If someone else is already canceling, wait for it to
|
||||
* finish. flush_work() doesn't work for PREEMPT_NONE
|
||||
* because we may get scheduled between @work's completion
|
||||
* and the other canceling task resuming and clearing
|
||||
* CANCELING - flush_work() will return false immediately
|
||||
* as @work is no longer busy, try_to_grab_pending() will
|
||||
* return -ENOENT as @work is still being canceled and the
|
||||
* other canceling task won't be able to clear CANCELING as
|
||||
* we're hogging the CPU.
|
||||
*
|
||||
* Let's wait for completion using a waitqueue. As this
|
||||
* may lead to the thundering herd problem, use a custom
|
||||
* wake function which matches @work along with exclusive
|
||||
* wait and wakeup.
|
||||
*/
|
||||
if (unlikely(ret == -ENOENT))
|
||||
flush_work(work);
|
||||
if (unlikely(ret == -ENOENT)) {
|
||||
struct cwt_wait cwait;
|
||||
|
||||
init_wait(&cwait.wait);
|
||||
cwait.wait.func = cwt_wakefn;
|
||||
cwait.work = work;
|
||||
|
||||
prepare_to_wait_exclusive(&cancel_waitq, &cwait.wait,
|
||||
TASK_UNINTERRUPTIBLE);
|
||||
if (work_is_canceling(work))
|
||||
schedule();
|
||||
finish_wait(&cancel_waitq, &cwait.wait);
|
||||
}
|
||||
} while (unlikely(ret < 0));
|
||||
|
||||
/* tell other tasks trying to grab @work to back off */
|
||||
@@ -2749,6 +2787,16 @@ static bool __cancel_work_timer(struct work_struct *work, bool is_dwork)
|
||||
|
||||
flush_work(work);
|
||||
clear_work_data(work);
|
||||
|
||||
/*
|
||||
* Paired with prepare_to_wait() above so that either
|
||||
* waitqueue_active() is visible here or !work_is_canceling() is
|
||||
* visible there.
|
||||
*/
|
||||
smp_mb();
|
||||
if (waitqueue_active(&cancel_waitq))
|
||||
__wake_up(&cancel_waitq, TASK_NORMAL, 1, work);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user