Hi Anders,
I resolved a conflicts when merge lsk 4.1 to lsk 4.1-rt. Could you like review it?
The merge branch pushed on lsk linux-linaro-lsk-v4.1-rt-test
Thanks Alex ---
commit 72316324660f953a8daee9bf9fcf942f7851b516 Merge: e91b1cc 7c0ca54 Author: Alex Shi alex.shi@linaro.org Date: Fri Jun 17 16:48:40 2016 +0800
Merge branch 'linux-linaro-lsk-v4.1' into linux-linaro-lsk-v4.1-rt
Conflicts: backport cg-writeback in include/linux/cgroup.h compatible with 28f83d2 futex: Handle unlock_pi race gracefull in kernel/futex.c
diff --cc arch/arm64/Kconfig index 1f05b35,2b5b0c5..d655358 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@@ -71,10 -72,9 +72,11 @@@ config ARM6 select HAVE_PERF_REGS select HAVE_PERF_USER_STACK_DUMP select HAVE_RCU_TABLE_FREE + select HAVE_PREEMPT_LAZY select HAVE_SYSCALL_TRACEPOINTS + select IOMMU_DMA if IOMMU_SUPPORT select IRQ_DOMAIN + select IRQ_FORCED_THREADING select MODULES_USE_ELF_RELA select NO_BOOTMEM select OF diff --cc include/linux/cgroup.h index e3f81b7,56e7af9..1e6f683 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h @@@ -16,24 -16,266 +16,268 @@@ #include <linux/fs.h> #include <linux/seq_file.h> #include <linux/kernfs.h> +#include <linux/wait.h> +#include <linux/work-simple.h> + #include <linux/jump_label.h>
#include <linux/cgroup-defs.h> - #ifdef CONFIG_CGROUPS + /* + * All weight knobs on the default hierarhcy should use the following min, + * default and max values. The default value is the logarithmic center of + * MIN and MAX and allows 100x to be expressed in both directions. + */ + #define CGROUP_WEIGHT_MIN 1 + #define CGROUP_WEIGHT_DFL 100 + #define CGROUP_WEIGHT_MAX 10000 + + /* a css_task_iter should be treated as an opaque object */ + struct css_task_iter { + struct cgroup_subsys *ss; + + struct list_head *cset_pos; + struct list_head *cset_head; + + struct list_head *task_pos; + struct list_head *tasks_head; + struct list_head *mg_tasks_head; + + struct css_set *cur_cset; + struct task_struct *cur_task; + struct list_head iters_node; /* css_set->task_iters */ + };
- extern int cgroup_init_early(void); - extern int cgroup_init(void); - extern void cgroup_fork(struct task_struct *p); - extern void cgroup_post_fork(struct task_struct *p); - extern void cgroup_exit(struct task_struct *p); - extern int cgroupstats_build(struct cgroupstats *stats, - struct dentry *dentry); + extern struct cgroup_root cgrp_dfl_root; + extern struct css_set init_css_set; + + #define SUBSYS(_x) extern struct cgroup_subsys _x ## _cgrp_subsys; + #include <linux/cgroup_subsys.h> + #undef SUBSYS
- extern int proc_cgroup_show(struct seq_file *m, struct pid_namespace *ns, - struct pid *pid, struct task_struct *tsk); + #define SUBSYS(_x) \ + extern struct static_key_true _x ## _cgrp_subsys_enabled_key; \ + extern struct static_key_true _x ## _cgrp_subsys_on_dfl_key; + #include <linux/cgroup_subsys.h> + #undef SUBSYS + + /** + * cgroup_subsys_enabled - fast test on whether a subsys is enabled + * @ss: subsystem in question + */ + #define cgroup_subsys_enabled(ss) \ + static_branch_likely(&ss ## _enabled_key) + + /** + * cgroup_subsys_on_dfl - fast test on whether a subsys is on default hierarchy + * @ss: subsystem in question + */ + #define cgroup_subsys_on_dfl(ss) \ + static_branch_likely(&ss ## _on_dfl_key) + + bool css_has_online_children(struct cgroup_subsys_state *css); + struct cgroup_subsys_state *css_from_id(int id, struct cgroup_subsys *ss); + struct cgroup_subsys_state *cgroup_get_e_css(struct cgroup *cgroup, + struct cgroup_subsys *ss); + struct cgroup_subsys_state *css_tryget_online_from_dir(struct dentry *dentry, + struct cgroup_subsys *ss); + + bool cgroup_is_descendant(struct cgroup *cgrp, struct cgroup *ancestor); + int cgroup_attach_task_all(struct task_struct *from, struct task_struct *); + int cgroup_transfer_tasks(struct cgroup *to, struct cgroup *from); + + int cgroup_add_dfl_cftypes(struct cgroup_subsys *ss, struct cftype *cfts); + int cgroup_add_legacy_cftypes(struct cgroup_subsys *ss, struct cftype *cfts); + int cgroup_rm_cftypes(struct cftype *cfts); + void cgroup_file_notify(struct cgroup_file *cfile); + + char *task_cgroup_path(struct task_struct *task, char *buf, size_t buflen); + int cgroupstats_build(struct cgroupstats *stats, struct dentry *dentry); + int proc_cgroup_show(struct seq_file *m, struct pid_namespace *ns, + struct pid *pid, struct task_struct *tsk); + + void cgroup_fork(struct task_struct *p); + extern int cgroup_can_fork(struct task_struct *p, + void *ss_priv[CGROUP_CANFORK_COUNT]); + extern void cgroup_cancel_fork(struct task_struct *p, + void *ss_priv[CGROUP_CANFORK_COUNT]); + extern void cgroup_post_fork(struct task_struct *p, + void *old_ss_priv[CGROUP_CANFORK_COUNT]); + void cgroup_exit(struct task_struct *p); + void cgroup_free(struct task_struct *p); + + int cgroup_init_early(void); + int cgroup_init(void); + + /* + * Iteration helpers and macros. + */ + + struct cgroup_subsys_state *css_next_child(struct cgroup_subsys_state *pos, + struct cgroup_subsys_state *parent); + struct cgroup_subsys_state *css_next_descendant_pre(struct cgroup_subsys_state *pos, + struct cgroup_subsys_state *css); + struct cgroup_subsys_state *css_rightmost_descendant(struct cgroup_subsys_state *pos); + struct cgroup_subsys_state *css_next_descendant_post(struct cgroup_subsys_state *pos, + struct cgroup_subsys_state *css); + + struct task_struct *cgroup_taskset_first(struct cgroup_taskset *tset, + struct cgroup_subsys_state **dst_cssp); + struct task_struct *cgroup_taskset_next(struct cgroup_taskset *tset, + struct cgroup_subsys_state **dst_cssp); + + void css_task_iter_start(struct cgroup_subsys_state *css, + struct css_task_iter *it); + struct task_struct *css_task_iter_next(struct css_task_iter *it); + void css_task_iter_end(struct css_task_iter *it); + + /** + * css_for_each_child - iterate through children of a css + * @pos: the css * to use as the loop cursor + * @parent: css whose children to walk + * + * Walk @parent's children. Must be called under rcu_read_lock(). + * + * If a subsystem synchronizes ->css_online() and the start of iteration, a + * css which finished ->css_online() is guaranteed to be visible in the + * future iterations and will stay visible until the last reference is put. + * A css which hasn't finished ->css_online() or already finished + * ->css_offline() may show up during traversal. It's each subsystem's + * responsibility to synchronize against on/offlining. + * + * It is allowed to temporarily drop RCU read lock during iteration. The + * caller is responsible for ensuring that @pos remains accessible until + * the start of the next iteration by, for example, bumping the css refcnt. + */ + #define css_for_each_child(pos, parent) \ + for ((pos) = css_next_child(NULL, (parent)); (pos); \ + (pos) = css_next_child((pos), (parent))) + + /** + * css_for_each_descendant_pre - pre-order walk of a css's descendants + * @pos: the css * to use as the loop cursor + * @root: css whose descendants to walk + * + * Walk @root's descendants. @root is included in the iteration and the + * first node to be visited. Must be called under rcu_read_lock(). + * + * If a subsystem synchronizes ->css_online() and the start of iteration, a + * css which finished ->css_online() is guaranteed to be visible in the + * future iterations and will stay visible until the last reference is put. + * A css which hasn't finished ->css_online() or already finished + * ->css_offline() may show up during traversal. It's each subsystem's + * responsibility to synchronize against on/offlining. + * + * For example, the following guarantees that a descendant can't escape + * state updates of its ancestors. + * + * my_online(@css) + * { + * Lock @css's parent and @css; + * Inherit state from the parent; + * Unlock both. + * } + * + * my_update_state(@css) + * { + * css_for_each_descendant_pre(@pos, @css) { + * Lock @pos; + * if (@pos == @css) + * Update @css's state; + * else + * Verify @pos is alive and inherit state from its parent; + * Unlock @pos; + * } + * } + * + * As long as the inheriting step, including checking the parent state, is + * enclosed inside @pos locking, double-locking the parent isn't necessary + * while inheriting. The state update to the parent is guaranteed to be + * visible by walking order and, as long as inheriting operations to the + * same @pos are atomic to each other, multiple updates racing each other + * still result in the correct state. It's guaranateed that at least one + * inheritance happens for any css after the latest update to its parent. + * + * If checking parent's state requires locking the parent, each inheriting + * iteration should lock and unlock both @pos->parent and @pos. + * + * Alternatively, a subsystem may choose to use a single global lock to + * synchronize ->css_online() and ->css_offline() against tree-walking + * operations. + * + * It is allowed to temporarily drop RCU read lock during iteration. The + * caller is responsible for ensuring that @pos remains accessible until + * the start of the next iteration by, for example, bumping the css refcnt. + */ + #define css_for_each_descendant_pre(pos, css) \ + for ((pos) = css_next_descendant_pre(NULL, (css)); (pos); \ + (pos) = css_next_descendant_pre((pos), (css))) + + /** + * css_for_each_descendant_post - post-order walk of a css's descendants + * @pos: the css * to use as the loop cursor + * @css: css whose descendants to walk + * + * Similar to css_for_each_descendant_pre() but performs post-order + * traversal instead. @root is included in the iteration and the last + * node to be visited. + * + * If a subsystem synchronizes ->css_online() and the start of iteration, a + * css which finished ->css_online() is guaranteed to be visible in the + * future iterations and will stay visible until the last reference is put. + * A css which hasn't finished ->css_online() or already finished + * ->css_offline() may show up during traversal. It's each subsystem's + * responsibility to synchronize against on/offlining. + * + * Note that the walk visibility guarantee example described in pre-order + * walk doesn't apply the same to post-order walks. + */ + #define css_for_each_descendant_post(pos, css) \ + for ((pos) = css_next_descendant_post(NULL, (css)); (pos); \ + (pos) = css_next_descendant_post((pos), (css))) + + /** + * cgroup_taskset_for_each - iterate cgroup_taskset + * @task: the loop cursor + * @dst_css: the destination css + * @tset: taskset to iterate + * + * @tset may contain multiple tasks and they may belong to multiple + * processes. + * + * On the v2 hierarchy, there may be tasks from multiple processes and they + * may not share the source or destination csses. + * + * On traditional hierarchies, when there are multiple tasks in @tset, if a + * task of a process is in @tset, all tasks of the process are in @tset. + * Also, all are guaranteed to share the same source and destination csses. + * + * Iteration is not in any specific order. + */ + #define cgroup_taskset_for_each(task, dst_css, tset) \ + for ((task) = cgroup_taskset_first((tset), &(dst_css)); \ + (task); \ + (task) = cgroup_taskset_next((tset), &(dst_css))) + + /** + * cgroup_taskset_for_each_leader - iterate group leaders in a cgroup_taskset + * @leader: the loop cursor + * @dst_css: the destination css + * @tset: takset to iterate + * + * Iterate threadgroup leaders of @tset. For single-task migrations, @tset + * may not contain any. + */ + #define cgroup_taskset_for_each_leader(leader, dst_css, tset) \ + for ((leader) = cgroup_taskset_first((tset), &(dst_css)); \ + (leader); \ + (leader) = cgroup_taskset_next((tset), &(dst_css))) \ + if ((leader) != (leader)->group_leader) \ + ; \ + else + + /* + * Inline functions. + */
/** * css_get - obtain a reference on the specified css diff --cc include/linux/sched.h index 2fd062b,f40a1af..590e49b --- a/include/linux/sched.h +++ b/include/linux/sched.h @@@ -1769,20 -1698,14 +1761,20 @@@ struct task_struct unsigned long trace; /* bitmask and counter of trace recursion */ unsigned long trace_recursion; +#ifdef CONFIG_WAKEUP_LATENCY_HIST + u64 preempt_timestamp_hist; +#ifdef CONFIG_MISSED_TIMER_OFFSETS_HIST + long timer_offset; +#endif +#endif #endif /* CONFIG_TRACING */ #ifdef CONFIG_MEMCG - struct memcg_oom_info { - struct mem_cgroup *memcg; - gfp_t gfp_mask; - int order; - unsigned int may_oom:1; - } memcg_oom; + struct mem_cgroup *memcg_in_oom; + gfp_t memcg_oom_gfp_mask; + int memcg_oom_order; + + /* number of pages to reclaim on returning to userland */ + unsigned int memcg_nr_pages_over_high; #endif #ifdef CONFIG_UPROBES struct uprobe_task *utask; diff --cc kernel/futex.c index e417491,46b168e..8422f94 --- a/kernel/futex.c +++ b/kernel/futex.c @@@ -2452,11 -2429,15 +2462,21 @@@ retry */ if (ret == -EFAULT) goto pi_faulted; + /* + * A unconditional UNLOCK_PI op raced against a waiter + * setting the FUTEX_WAITERS bit. Try again. + */ + if (ret == -EAGAIN) { + spin_unlock(&hb->lock); + put_futex_key(&key); + goto retry; + } ++ ++ /* + * wake_futex_pi has detected invalid state. Tell user + * space. + */ goto out_unlock; }
Hi Anders,
Could you have time to see this solution?
Alex
On 06/17/2016 04:54 PM, Alex Shi wrote:
Hi Anders,
I resolved a conflicts when merge lsk 4.1 to lsk 4.1-rt. Could you like review it?
The merge branch pushed on lsk linux-linaro-lsk-v4.1-rt-test
Thanks Alex
commit 72316324660f953a8daee9bf9fcf942f7851b516 Merge: e91b1cc 7c0ca54 Author: Alex Shi alex.shi@linaro.org Date: Fri Jun 17 16:48:40 2016 +0800
Merge branch 'linux-linaro-lsk-v4.1' into linux-linaro-lsk-v4.1-rt
Conflicts: backport cg-writeback in include/linux/cgroup.h compatible with 28f83d2 futex: Handle unlock_pi race gracefull in kernel/futex.c
diff --cc arch/arm64/Kconfig index 1f05b35,2b5b0c5..d655358 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@@ -71,10 -72,9 +72,11 @@@ config ARM6 select HAVE_PERF_REGS select HAVE_PERF_USER_STACK_DUMP select HAVE_RCU_TABLE_FREE
- select HAVE_PREEMPT_LAZY select HAVE_SYSCALL_TRACEPOINTS
- select IOMMU_DMA if IOMMU_SUPPORT select IRQ_DOMAIN
- select IRQ_FORCED_THREADING select MODULES_USE_ELF_RELA select NO_BOOTMEM select OF
diff --cc include/linux/cgroup.h index e3f81b7,56e7af9..1e6f683 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h @@@ -16,24 -16,266 +16,268 @@@ #include <linux/fs.h> #include <linux/seq_file.h> #include <linux/kernfs.h> +#include <linux/wait.h> +#include <linux/work-simple.h>
- #include <linux/jump_label.h>
#include <linux/cgroup-defs.h>
- #ifdef CONFIG_CGROUPS
- /*
- All weight knobs on the default hierarhcy should use the following min,
- default and max values. The default value is the logarithmic center of
- MIN and MAX and allows 100x to be expressed in both directions.
- */
- #define CGROUP_WEIGHT_MIN 1
- #define CGROUP_WEIGHT_DFL 100
- #define CGROUP_WEIGHT_MAX 10000
- /* a css_task_iter should be treated as an opaque object */
- struct css_task_iter {
- struct cgroup_subsys *ss;
- struct list_head *cset_pos;
- struct list_head *cset_head;
- struct list_head *task_pos;
- struct list_head *tasks_head;
- struct list_head *mg_tasks_head;
- struct css_set *cur_cset;
- struct task_struct *cur_task;
- struct list_head iters_node; /* css_set->task_iters */
- };
- extern int cgroup_init_early(void);
- extern int cgroup_init(void);
- extern void cgroup_fork(struct task_struct *p);
- extern void cgroup_post_fork(struct task_struct *p);
- extern void cgroup_exit(struct task_struct *p);
- extern int cgroupstats_build(struct cgroupstats *stats,
struct dentry *dentry);
- extern struct cgroup_root cgrp_dfl_root;
- extern struct css_set init_css_set;
- #define SUBSYS(_x) extern struct cgroup_subsys _x ## _cgrp_subsys;
- #include <linux/cgroup_subsys.h>
- #undef SUBSYS
- extern int proc_cgroup_show(struct seq_file *m, struct pid_namespace *ns,
struct pid *pid, struct task_struct *tsk);
- #define SUBSYS(_x) \
- extern struct static_key_true _x ## _cgrp_subsys_enabled_key; \
- extern struct static_key_true _x ## _cgrp_subsys_on_dfl_key;
- #include <linux/cgroup_subsys.h>
- #undef SUBSYS
- /**
- cgroup_subsys_enabled - fast test on whether a subsys is enabled
- @ss: subsystem in question
- */
- #define cgroup_subsys_enabled(ss) \
- static_branch_likely(&ss ## _enabled_key)
- /**
- cgroup_subsys_on_dfl - fast test on whether a subsys is on default hierarchy
- @ss: subsystem in question
- */
- #define cgroup_subsys_on_dfl(ss) \
- static_branch_likely(&ss ## _on_dfl_key)
- bool css_has_online_children(struct cgroup_subsys_state *css);
- struct cgroup_subsys_state *css_from_id(int id, struct cgroup_subsys *ss);
- struct cgroup_subsys_state *cgroup_get_e_css(struct cgroup *cgroup,
struct cgroup_subsys *ss);
- struct cgroup_subsys_state *css_tryget_online_from_dir(struct dentry *dentry,
struct cgroup_subsys *ss);
- bool cgroup_is_descendant(struct cgroup *cgrp, struct cgroup *ancestor);
- int cgroup_attach_task_all(struct task_struct *from, struct task_struct *);
- int cgroup_transfer_tasks(struct cgroup *to, struct cgroup *from);
- int cgroup_add_dfl_cftypes(struct cgroup_subsys *ss, struct cftype *cfts);
- int cgroup_add_legacy_cftypes(struct cgroup_subsys *ss, struct cftype *cfts);
- int cgroup_rm_cftypes(struct cftype *cfts);
- void cgroup_file_notify(struct cgroup_file *cfile);
- char *task_cgroup_path(struct task_struct *task, char *buf, size_t buflen);
- int cgroupstats_build(struct cgroupstats *stats, struct dentry *dentry);
- int proc_cgroup_show(struct seq_file *m, struct pid_namespace *ns,
struct pid *pid, struct task_struct *tsk);
- void cgroup_fork(struct task_struct *p);
- extern int cgroup_can_fork(struct task_struct *p,
void *ss_priv[CGROUP_CANFORK_COUNT]);
- extern void cgroup_cancel_fork(struct task_struct *p,
void *ss_priv[CGROUP_CANFORK_COUNT]);
- extern void cgroup_post_fork(struct task_struct *p,
void *old_ss_priv[CGROUP_CANFORK_COUNT]);
- void cgroup_exit(struct task_struct *p);
- void cgroup_free(struct task_struct *p);
- int cgroup_init_early(void);
- int cgroup_init(void);
- /*
- Iteration helpers and macros.
- */
- struct cgroup_subsys_state *css_next_child(struct cgroup_subsys_state *pos,
struct cgroup_subsys_state *parent);
- struct cgroup_subsys_state *css_next_descendant_pre(struct cgroup_subsys_state *pos,
struct cgroup_subsys_state *css);
- struct cgroup_subsys_state *css_rightmost_descendant(struct cgroup_subsys_state *pos);
- struct cgroup_subsys_state *css_next_descendant_post(struct cgroup_subsys_state *pos,
struct cgroup_subsys_state *css);
- struct task_struct *cgroup_taskset_first(struct cgroup_taskset *tset,
struct cgroup_subsys_state **dst_cssp);
- struct task_struct *cgroup_taskset_next(struct cgroup_taskset *tset,
struct cgroup_subsys_state **dst_cssp);
- void css_task_iter_start(struct cgroup_subsys_state *css,
struct css_task_iter *it);
- struct task_struct *css_task_iter_next(struct css_task_iter *it);
- void css_task_iter_end(struct css_task_iter *it);
- /**
- css_for_each_child - iterate through children of a css
- @pos: the css * to use as the loop cursor
- @parent: css whose children to walk
- Walk @parent's children. Must be called under rcu_read_lock().
- If a subsystem synchronizes ->css_online() and the start of iteration, a
- css which finished ->css_online() is guaranteed to be visible in the
- future iterations and will stay visible until the last reference is put.
- A css which hasn't finished ->css_online() or already finished
- ->css_offline() may show up during traversal. It's each subsystem's
- responsibility to synchronize against on/offlining.
- It is allowed to temporarily drop RCU read lock during iteration. The
- caller is responsible for ensuring that @pos remains accessible until
- the start of the next iteration by, for example, bumping the css refcnt.
- */
- #define css_for_each_child(pos, parent) \
- for ((pos) = css_next_child(NULL, (parent)); (pos); \
(pos) = css_next_child((pos), (parent)))
- /**
- css_for_each_descendant_pre - pre-order walk of a css's descendants
- @pos: the css * to use as the loop cursor
- @root: css whose descendants to walk
- Walk @root's descendants. @root is included in the iteration and the
- first node to be visited. Must be called under rcu_read_lock().
- If a subsystem synchronizes ->css_online() and the start of iteration, a
- css which finished ->css_online() is guaranteed to be visible in the
- future iterations and will stay visible until the last reference is put.
- A css which hasn't finished ->css_online() or already finished
- ->css_offline() may show up during traversal. It's each subsystem's
- responsibility to synchronize against on/offlining.
- For example, the following guarantees that a descendant can't escape
- state updates of its ancestors.
- my_online(@css)
- {
- Lock @css's parent and @css;
- Inherit state from the parent;
- Unlock both.
- }
- my_update_state(@css)
- {
- css_for_each_descendant_pre(@pos, @css) {
Lock @pos;
if (@pos == @css)
Update @css's state;
else
Verify @pos is alive and inherit state from its parent;
Unlock @pos;
- }
- }
- As long as the inheriting step, including checking the parent state, is
- enclosed inside @pos locking, double-locking the parent isn't necessary
- while inheriting. The state update to the parent is guaranteed to be
- visible by walking order and, as long as inheriting operations to the
- same @pos are atomic to each other, multiple updates racing each other
- still result in the correct state. It's guaranateed that at least one
- inheritance happens for any css after the latest update to its parent.
- If checking parent's state requires locking the parent, each inheriting
- iteration should lock and unlock both @pos->parent and @pos.
- Alternatively, a subsystem may choose to use a single global lock to
- synchronize ->css_online() and ->css_offline() against tree-walking
- operations.
- It is allowed to temporarily drop RCU read lock during iteration. The
- caller is responsible for ensuring that @pos remains accessible until
- the start of the next iteration by, for example, bumping the css refcnt.
- */
- #define css_for_each_descendant_pre(pos, css) \
- for ((pos) = css_next_descendant_pre(NULL, (css)); (pos); \
(pos) = css_next_descendant_pre((pos), (css)))
- /**
- css_for_each_descendant_post - post-order walk of a css's descendants
- @pos: the css * to use as the loop cursor
- @css: css whose descendants to walk
- Similar to css_for_each_descendant_pre() but performs post-order
- traversal instead. @root is included in the iteration and the last
- node to be visited.
- If a subsystem synchronizes ->css_online() and the start of iteration, a
- css which finished ->css_online() is guaranteed to be visible in the
- future iterations and will stay visible until the last reference is put.
- A css which hasn't finished ->css_online() or already finished
- ->css_offline() may show up during traversal. It's each subsystem's
- responsibility to synchronize against on/offlining.
- Note that the walk visibility guarantee example described in pre-order
- walk doesn't apply the same to post-order walks.
- */
- #define css_for_each_descendant_post(pos, css) \
- for ((pos) = css_next_descendant_post(NULL, (css)); (pos); \
(pos) = css_next_descendant_post((pos), (css)))
- /**
- cgroup_taskset_for_each - iterate cgroup_taskset
- @task: the loop cursor
- @dst_css: the destination css
- @tset: taskset to iterate
- @tset may contain multiple tasks and they may belong to multiple
- processes.
- On the v2 hierarchy, there may be tasks from multiple processes and they
- may not share the source or destination csses.
- On traditional hierarchies, when there are multiple tasks in @tset, if a
- task of a process is in @tset, all tasks of the process are in @tset.
- Also, all are guaranteed to share the same source and destination csses.
- Iteration is not in any specific order.
- */
- #define cgroup_taskset_for_each(task, dst_css, tset) \
- for ((task) = cgroup_taskset_first((tset), &(dst_css)); \
(task); \
(task) = cgroup_taskset_next((tset), &(dst_css)))
- /**
- cgroup_taskset_for_each_leader - iterate group leaders in a cgroup_taskset
- @leader: the loop cursor
- @dst_css: the destination css
- @tset: takset to iterate
- Iterate threadgroup leaders of @tset. For single-task migrations, @tset
- may not contain any.
- */
- #define cgroup_taskset_for_each_leader(leader, dst_css, tset) \
- for ((leader) = cgroup_taskset_first((tset), &(dst_css)); \
(leader); \
(leader) = cgroup_taskset_next((tset), &(dst_css))) \
if ((leader) != (leader)->group_leader) \
; \
else
- /*
- Inline functions.
- */
/**
- css_get - obtain a reference on the specified css
diff --cc include/linux/sched.h index 2fd062b,f40a1af..590e49b --- a/include/linux/sched.h +++ b/include/linux/sched.h @@@ -1769,20 -1698,14 +1761,20 @@@ struct task_struct unsigned long trace; /* bitmask and counter of trace recursion */ unsigned long trace_recursion; +#ifdef CONFIG_WAKEUP_LATENCY_HIST
- u64 preempt_timestamp_hist;
+#ifdef CONFIG_MISSED_TIMER_OFFSETS_HIST
- long timer_offset;
+#endif +#endif #endif /* CONFIG_TRACING */ #ifdef CONFIG_MEMCG
- struct memcg_oom_info {
struct mem_cgroup *memcg;
gfp_t gfp_mask;
int order;
unsigned int may_oom:1;
- } memcg_oom;
- struct mem_cgroup *memcg_in_oom;
- gfp_t memcg_oom_gfp_mask;
- int memcg_oom_order;
- /* number of pages to reclaim on returning to userland */
- unsigned int memcg_nr_pages_over_high; #endif #ifdef CONFIG_UPROBES struct uprobe_task *utask;
diff --cc kernel/futex.c index e417491,46b168e..8422f94 --- a/kernel/futex.c +++ b/kernel/futex.c @@@ -2452,11 -2429,15 +2462,21 @@@ retry */ if (ret == -EFAULT) goto pi_faulted;
- /*
* A unconditional UNLOCK_PI op raced against a waiter
* setting the FUTEX_WAITERS bit. Try again.
*/
if (ret == -EAGAIN) {
spin_unlock(&hb->lock);
put_futex_key(&key);
goto retry;
}
++ ++ /*
* wake_futex_pi has detected invalid state. Tell user
* space.
goto out_unlock; }*/
Hi Ander,
As long time no response from, I pushed this merge.
Alex
On 06/23/2016 10:52 PM, Alex Shi wrote:
Hi Anders,
Could you have time to see this solution?
Alex
On 06/17/2016 04:54 PM, Alex Shi wrote:
Hi Anders,
I resolved a conflicts when merge lsk 4.1 to lsk 4.1-rt. Could you like review it?
The merge branch pushed on lsk linux-linaro-lsk-v4.1-rt-test
Thanks Alex
commit 72316324660f953a8daee9bf9fcf942f7851b516 Merge: e91b1cc 7c0ca54 Author: Alex Shi alex.shi@linaro.org Date: Fri Jun 17 16:48:40 2016 +0800
Merge branch 'linux-linaro-lsk-v4.1' into linux-linaro-lsk-v4.1-rt
Conflicts: backport cg-writeback in include/linux/cgroup.h compatible with 28f83d2 futex: Handle unlock_pi race gracefull in kernel/futex.c
diff --cc arch/arm64/Kconfig index 1f05b35,2b5b0c5..d655358 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@@ -71,10 -72,9 +72,11 @@@ config ARM6 select HAVE_PERF_REGS select HAVE_PERF_USER_STACK_DUMP select HAVE_RCU_TABLE_FREE
- select HAVE_PREEMPT_LAZY select HAVE_SYSCALL_TRACEPOINTS
- select IOMMU_DMA if IOMMU_SUPPORT select IRQ_DOMAIN
- select IRQ_FORCED_THREADING select MODULES_USE_ELF_RELA select NO_BOOTMEM select OF
diff --cc include/linux/cgroup.h index e3f81b7,56e7af9..1e6f683 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h @@@ -16,24 -16,266 +16,268 @@@ #include <linux/fs.h> #include <linux/seq_file.h> #include <linux/kernfs.h> +#include <linux/wait.h> +#include <linux/work-simple.h>
- #include <linux/jump_label.h>
#include <linux/cgroup-defs.h>
- #ifdef CONFIG_CGROUPS
- /*
- All weight knobs on the default hierarhcy should use the following min,
- default and max values. The default value is the logarithmic center of
- MIN and MAX and allows 100x to be expressed in both directions.
- */
- #define CGROUP_WEIGHT_MIN 1
- #define CGROUP_WEIGHT_DFL 100
- #define CGROUP_WEIGHT_MAX 10000
- /* a css_task_iter should be treated as an opaque object */
- struct css_task_iter {
- struct cgroup_subsys *ss;
- struct list_head *cset_pos;
- struct list_head *cset_head;
- struct list_head *task_pos;
- struct list_head *tasks_head;
- struct list_head *mg_tasks_head;
- struct css_set *cur_cset;
- struct task_struct *cur_task;
- struct list_head iters_node; /* css_set->task_iters */
- };
- extern int cgroup_init_early(void);
- extern int cgroup_init(void);
- extern void cgroup_fork(struct task_struct *p);
- extern void cgroup_post_fork(struct task_struct *p);
- extern void cgroup_exit(struct task_struct *p);
- extern int cgroupstats_build(struct cgroupstats *stats,
struct dentry *dentry);
- extern struct cgroup_root cgrp_dfl_root;
- extern struct css_set init_css_set;
- #define SUBSYS(_x) extern struct cgroup_subsys _x ## _cgrp_subsys;
- #include <linux/cgroup_subsys.h>
- #undef SUBSYS
- extern int proc_cgroup_show(struct seq_file *m, struct pid_namespace *ns,
struct pid *pid, struct task_struct *tsk);
- #define SUBSYS(_x) \
- extern struct static_key_true _x ## _cgrp_subsys_enabled_key; \
- extern struct static_key_true _x ## _cgrp_subsys_on_dfl_key;
- #include <linux/cgroup_subsys.h>
- #undef SUBSYS
- /**
- cgroup_subsys_enabled - fast test on whether a subsys is enabled
- @ss: subsystem in question
- */
- #define cgroup_subsys_enabled(ss) \
- static_branch_likely(&ss ## _enabled_key)
- /**
- cgroup_subsys_on_dfl - fast test on whether a subsys is on default hierarchy
- @ss: subsystem in question
- */
- #define cgroup_subsys_on_dfl(ss) \
- static_branch_likely(&ss ## _on_dfl_key)
- bool css_has_online_children(struct cgroup_subsys_state *css);
- struct cgroup_subsys_state *css_from_id(int id, struct cgroup_subsys *ss);
- struct cgroup_subsys_state *cgroup_get_e_css(struct cgroup *cgroup,
struct cgroup_subsys *ss);
- struct cgroup_subsys_state *css_tryget_online_from_dir(struct dentry *dentry,
struct cgroup_subsys *ss);
- bool cgroup_is_descendant(struct cgroup *cgrp, struct cgroup *ancestor);
- int cgroup_attach_task_all(struct task_struct *from, struct task_struct *);
- int cgroup_transfer_tasks(struct cgroup *to, struct cgroup *from);
- int cgroup_add_dfl_cftypes(struct cgroup_subsys *ss, struct cftype *cfts);
- int cgroup_add_legacy_cftypes(struct cgroup_subsys *ss, struct cftype *cfts);
- int cgroup_rm_cftypes(struct cftype *cfts);
- void cgroup_file_notify(struct cgroup_file *cfile);
- char *task_cgroup_path(struct task_struct *task, char *buf, size_t buflen);
- int cgroupstats_build(struct cgroupstats *stats, struct dentry *dentry);
- int proc_cgroup_show(struct seq_file *m, struct pid_namespace *ns,
struct pid *pid, struct task_struct *tsk);
- void cgroup_fork(struct task_struct *p);
- extern int cgroup_can_fork(struct task_struct *p,
void *ss_priv[CGROUP_CANFORK_COUNT]);
- extern void cgroup_cancel_fork(struct task_struct *p,
void *ss_priv[CGROUP_CANFORK_COUNT]);
- extern void cgroup_post_fork(struct task_struct *p,
void *old_ss_priv[CGROUP_CANFORK_COUNT]);
- void cgroup_exit(struct task_struct *p);
- void cgroup_free(struct task_struct *p);
- int cgroup_init_early(void);
- int cgroup_init(void);
- /*
- Iteration helpers and macros.
- */
- struct cgroup_subsys_state *css_next_child(struct cgroup_subsys_state *pos,
struct cgroup_subsys_state *parent);
- struct cgroup_subsys_state *css_next_descendant_pre(struct cgroup_subsys_state *pos,
struct cgroup_subsys_state *css);
- struct cgroup_subsys_state *css_rightmost_descendant(struct cgroup_subsys_state *pos);
- struct cgroup_subsys_state *css_next_descendant_post(struct cgroup_subsys_state *pos,
struct cgroup_subsys_state *css);
- struct task_struct *cgroup_taskset_first(struct cgroup_taskset *tset,
struct cgroup_subsys_state **dst_cssp);
- struct task_struct *cgroup_taskset_next(struct cgroup_taskset *tset,
struct cgroup_subsys_state **dst_cssp);
- void css_task_iter_start(struct cgroup_subsys_state *css,
struct css_task_iter *it);
- struct task_struct *css_task_iter_next(struct css_task_iter *it);
- void css_task_iter_end(struct css_task_iter *it);
- /**
- css_for_each_child - iterate through children of a css
- @pos: the css * to use as the loop cursor
- @parent: css whose children to walk
- Walk @parent's children. Must be called under rcu_read_lock().
- If a subsystem synchronizes ->css_online() and the start of iteration, a
- css which finished ->css_online() is guaranteed to be visible in the
- future iterations and will stay visible until the last reference is put.
- A css which hasn't finished ->css_online() or already finished
- ->css_offline() may show up during traversal. It's each subsystem's
- responsibility to synchronize against on/offlining.
- It is allowed to temporarily drop RCU read lock during iteration. The
- caller is responsible for ensuring that @pos remains accessible until
- the start of the next iteration by, for example, bumping the css refcnt.
- */
- #define css_for_each_child(pos, parent) \
- for ((pos) = css_next_child(NULL, (parent)); (pos); \
(pos) = css_next_child((pos), (parent)))
- /**
- css_for_each_descendant_pre - pre-order walk of a css's descendants
- @pos: the css * to use as the loop cursor
- @root: css whose descendants to walk
- Walk @root's descendants. @root is included in the iteration and the
- first node to be visited. Must be called under rcu_read_lock().
- If a subsystem synchronizes ->css_online() and the start of iteration, a
- css which finished ->css_online() is guaranteed to be visible in the
- future iterations and will stay visible until the last reference is put.
- A css which hasn't finished ->css_online() or already finished
- ->css_offline() may show up during traversal. It's each subsystem's
- responsibility to synchronize against on/offlining.
- For example, the following guarantees that a descendant can't escape
- state updates of its ancestors.
- my_online(@css)
- {
- Lock @css's parent and @css;
- Inherit state from the parent;
- Unlock both.
- }
- my_update_state(@css)
- {
- css_for_each_descendant_pre(@pos, @css) {
Lock @pos;
if (@pos == @css)
Update @css's state;
else
Verify @pos is alive and inherit state from its parent;
Unlock @pos;
- }
- }
- As long as the inheriting step, including checking the parent state, is
- enclosed inside @pos locking, double-locking the parent isn't necessary
- while inheriting. The state update to the parent is guaranteed to be
- visible by walking order and, as long as inheriting operations to the
- same @pos are atomic to each other, multiple updates racing each other
- still result in the correct state. It's guaranateed that at least one
- inheritance happens for any css after the latest update to its parent.
- If checking parent's state requires locking the parent, each inheriting
- iteration should lock and unlock both @pos->parent and @pos.
- Alternatively, a subsystem may choose to use a single global lock to
- synchronize ->css_online() and ->css_offline() against tree-walking
- operations.
- It is allowed to temporarily drop RCU read lock during iteration. The
- caller is responsible for ensuring that @pos remains accessible until
- the start of the next iteration by, for example, bumping the css refcnt.
- */
- #define css_for_each_descendant_pre(pos, css) \
- for ((pos) = css_next_descendant_pre(NULL, (css)); (pos); \
(pos) = css_next_descendant_pre((pos), (css)))
- /**
- css_for_each_descendant_post - post-order walk of a css's descendants
- @pos: the css * to use as the loop cursor
- @css: css whose descendants to walk
- Similar to css_for_each_descendant_pre() but performs post-order
- traversal instead. @root is included in the iteration and the last
- node to be visited.
- If a subsystem synchronizes ->css_online() and the start of iteration, a
- css which finished ->css_online() is guaranteed to be visible in the
- future iterations and will stay visible until the last reference is put.
- A css which hasn't finished ->css_online() or already finished
- ->css_offline() may show up during traversal. It's each subsystem's
- responsibility to synchronize against on/offlining.
- Note that the walk visibility guarantee example described in pre-order
- walk doesn't apply the same to post-order walks.
- */
- #define css_for_each_descendant_post(pos, css) \
- for ((pos) = css_next_descendant_post(NULL, (css)); (pos); \
(pos) = css_next_descendant_post((pos), (css)))
- /**
- cgroup_taskset_for_each - iterate cgroup_taskset
- @task: the loop cursor
- @dst_css: the destination css
- @tset: taskset to iterate
- @tset may contain multiple tasks and they may belong to multiple
- processes.
- On the v2 hierarchy, there may be tasks from multiple processes and they
- may not share the source or destination csses.
- On traditional hierarchies, when there are multiple tasks in @tset, if a
- task of a process is in @tset, all tasks of the process are in @tset.
- Also, all are guaranteed to share the same source and destination csses.
- Iteration is not in any specific order.
- */
- #define cgroup_taskset_for_each(task, dst_css, tset) \
- for ((task) = cgroup_taskset_first((tset), &(dst_css)); \
(task); \
(task) = cgroup_taskset_next((tset), &(dst_css)))
- /**
- cgroup_taskset_for_each_leader - iterate group leaders in a cgroup_taskset
- @leader: the loop cursor
- @dst_css: the destination css
- @tset: takset to iterate
- Iterate threadgroup leaders of @tset. For single-task migrations, @tset
- may not contain any.
- */
- #define cgroup_taskset_for_each_leader(leader, dst_css, tset) \
- for ((leader) = cgroup_taskset_first((tset), &(dst_css)); \
(leader); \
(leader) = cgroup_taskset_next((tset), &(dst_css))) \
if ((leader) != (leader)->group_leader) \
; \
else
- /*
- Inline functions.
- */
/**
- css_get - obtain a reference on the specified css
diff --cc include/linux/sched.h index 2fd062b,f40a1af..590e49b --- a/include/linux/sched.h +++ b/include/linux/sched.h @@@ -1769,20 -1698,14 +1761,20 @@@ struct task_struct unsigned long trace; /* bitmask and counter of trace recursion */ unsigned long trace_recursion; +#ifdef CONFIG_WAKEUP_LATENCY_HIST
- u64 preempt_timestamp_hist;
+#ifdef CONFIG_MISSED_TIMER_OFFSETS_HIST
- long timer_offset;
+#endif +#endif #endif /* CONFIG_TRACING */ #ifdef CONFIG_MEMCG
- struct memcg_oom_info {
struct mem_cgroup *memcg;
gfp_t gfp_mask;
int order;
unsigned int may_oom:1;
- } memcg_oom;
- struct mem_cgroup *memcg_in_oom;
- gfp_t memcg_oom_gfp_mask;
- int memcg_oom_order;
- /* number of pages to reclaim on returning to userland */
- unsigned int memcg_nr_pages_over_high; #endif #ifdef CONFIG_UPROBES struct uprobe_task *utask;
diff --cc kernel/futex.c index e417491,46b168e..8422f94 --- a/kernel/futex.c +++ b/kernel/futex.c @@@ -2452,11 -2429,15 +2462,21 @@@ retry */ if (ret == -EFAULT) goto pi_faulted;
- /*
* A unconditional UNLOCK_PI op raced against a waiter
* setting the FUTEX_WAITERS bit. Try again.
*/
if (ret == -EAGAIN) {
spin_unlock(&hb->lock);
put_futex_key(&key);
goto retry;
}
++ ++ /*
* wake_futex_pi has detected invalid state. Tell user
* space.
goto out_unlock; }*/
linaro-kernel@lists.linaro.org