4.12.4-stable review
Subsystems (6)
Greg Kroah-Hartman
maintainerPATCH 174/196 vtime, sched/cputime: Remove vtime_account_user()
In reply to Greg Kroah-Hartman4.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Frederic Weisbecker <[email protected]>
commit 1c3eda01a79b8e9237d91c52c5a75b20983f47c6 upstream.
It's an unnecessary function between vtime_user_exit() and account_user_time().
--- include/linux/vtime.h | 9 +-------- kernel/sched/cputime.c | 12 ++++++------ 2 files changed, 7 insertions(+), 14 deletions(-)
include/linux/vtime.h +1 -8
@@ -67,19 +67,12 @@ static inline void vtime_account_system(#ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN extern void arch_vtime_task_switch (struct task_struct *tsk); -extern void vtime_account_user (struct task_struct *tsk);extern void vtime_user_enter (struct task_struct *tsk); - -static inline void vtime_user_exit (struct task_struct *tsk) -{ -vtime_account_user (tsk); -} - +extern void vtime_user_exit (struct task_struct *tsk);extern void vtime_guest_enter (struct task_struct *tsk);extern void vtime_guest_exit (struct task_struct *tsk);extern void vtime_init_idle (struct task_struct *tsk,int cpu);#else /* !CONFIG_VIRT_CPU_ACCOUNTING_GEN */ -static inline void vtime_account_user (struct task_struct *tsk) { }static inline void vtime_user_enter (struct task_struct *tsk) { }static inline void vtime_user_exit (struct task_struct *tsk) { }static inline void vtime_guest_enter (struct task_struct *tsk) { }
kernel/sched/cputime.c +6 -6
@@ -724,21 +724,21 @@ void vtime_account_system(struct task_stwrite_seqcount_end (&tsk->vtime_seqcount); } -void vtime_account_user (struct task_struct *tsk) +void vtime_user_enter (struct task_struct *tsk) {write_seqcount_begin (&tsk->vtime_seqcount); - tsk->vtime_snap_whence =VTIME_SYS ;if (vtime_delta (tsk)) -account_user_time (tsk,get_vtime_delta (tsk)); +__vtime_account_system (tsk); + tsk->vtime_snap_whence =VTIME_USER ;write_seqcount_end (&tsk->vtime_seqcount); } -void vtime_user_enter (struct task_struct *tsk) +void vtime_user_exit (struct task_struct *tsk) {write_seqcount_begin (&tsk->vtime_seqcount); + tsk->vtime_snap_whence =VTIME_SYS ;if (vtime_delta (tsk)) -__vtime_account_system (tsk); - tsk->vtime_snap_whence =VTIME_USER ; +account_user_time (tsk,get_vtime_delta (tsk));write_seqcount_end (&tsk->vtime_seqcount); }
Greg Kroah-Hartman
maintainerPATCH 175/196 sched/cputime: Always set tsk->vtime_snap_whence after accounting vtime
In reply to Greg Kroah-Hartman4.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Frederic Weisbecker <[email protected]>
commit 9fa57cf5a5c4aed1e45879b335fe433048709327 upstream.
Even though it doesn't have functional consequences, setting the task's new context state after we actually accounted the pending vtime from the old context state makes more sense from a review perspective.
vtime_user_exit() is the only function that doesn't follow that rule and that can bug the reviewer for a little while until he realizes there is no reason for this special case.
--- kernel/sched/cputime.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/sched/cputime.c +1 -1
@@ -736,9 +736,9 @@ void vtime_user_enter(struct task_structvoid vtime_user_exit (struct task_struct *tsk) {write_seqcount_begin (&tsk->vtime_seqcount); - tsk->vtime_snap_whence =VTIME_SYS ;if (vtime_delta (tsk))account_user_time (tsk,get_vtime_delta (tsk)); + tsk->vtime_snap_whence =VTIME_SYS ;write_seqcount_end (&tsk->vtime_seqcount); }
Greg Kroah-Hartman
maintainerPATCH 176/196 sched/cputime: Rename vtime fields
In reply to Greg Kroah-Hartman4.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Frederic Weisbecker <[email protected]>
commit 60a9ce57e7c5ac1df3a39fb941022bbfa40c0862 upstream.
The current "snapshot" based naming on vtime fields suggests we record some past event but that's a low level picture of their actual purpose which comes out blurry. The real point of these fields is to run a basic state machine that tracks down cputime entry while switching between contexts.
So lets reflect that with more meaningful names.
--- include/linux/init_task.h | 4 ++-- include/linux/sched.h | 4 ++-- kernel/fork.c | 4 ++-- kernel/sched/cputime.c | 30 +++++++++++++++--------------- 4 files changed, 21 insertions(+), 21 deletions(-)
include/linux/init_task.h +2 -2
@@ -171,8 +171,8 @@ extern struct cred init_cred;#ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN # define INIT_VTIME (tsk) \ .vtime_seqcount = SEQCNT_ZERO(tsk.vtime_seqcount), \ - .vtime_snap = 0, \ - .vtime_snap_whence = VTIME_SYS, + .vtime_starttime = 0, \ + .vtime_state = VTIME_SYS,#else # define INIT_VTIME (tsk)#endif
include/linux/sched.h +2 -2
@@ -671,7 +671,7 @@ struct task_struct {struct prev_cputime prev_cputime;#ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN seqcount_t vtime_seqcount; -unsigned long long vtime_snap; +unsigned long long vtime_starttime;enum {/* Task is sleeping or running in a CPU with VTIME inactive: */ VTIME_INACTIVE = 0,
@@ -679,7 +679,7 @@ struct task_struct {VTIME_USER ,/* Task runs in kernelspace in a CPU with VTIME active: */ VTIME_SYS , - } vtime_snap_whence; + } vtime_state;#endif #ifdef CONFIG_NO_HZ_FULL
kernel/fork.c +2 -2
@@ -1638,8 +1638,8 @@ static __latent_entropy struct task_stru#ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN seqcount_init (&p->vtime_seqcount); - p->vtime_snap =0 ; - p->vtime_snap_whence =VTIME_INACTIVE ; + p->vtime_starttime =0 ; + p->vtime_state =VTIME_INACTIVE ;#endif #if defined(SPLIT_RSS_COUNTING )
kernel/sched/cputime.c +15 -15
@@ -683,10 +683,10 @@ static u64 vtime_delta(struct task_struc {unsigned long now =READ_ONCE (jiffies); -if (time_before (now, (unsigned long )tsk->vtime_snap)) +if (time_before (now, (unsigned long )tsk->vtime_starttime))return 0 ; -return jiffies_to_nsecs (now - tsk->vtime_snap); +return jiffies_to_nsecs (now - tsk->vtime_starttime); }static u64 get_vtime_delta (struct task_struct *tsk)
@@ -701,10 +701,10 @@ static u64 get_vtime_delta(struct task_s* elapsed time. Limit account_other_time to prevent rounding * errors from causing elapsed vtime to go negative. */ - delta =jiffies_to_nsecs (now - tsk->vtime_snap); + delta =jiffies_to_nsecs (now - tsk->vtime_starttime); other =account_other_time (delta); -WARN_ON_ONCE (tsk->vtime_snap_whence ==VTIME_INACTIVE ); - tsk->vtime_snap = now; +WARN_ON_ONCE (tsk->vtime_state ==VTIME_INACTIVE ); + tsk->vtime_starttime = now;return delta - other; }
@@ -746,7 +746,7 @@ void vtime_guest_enter(struct task_struc {/* * The flags must be updated under the lock with -* the vtime_snap flush and update. +* the vtime_starttime flush and update. * That enforces a right ordering and update sequence * synchronization against the reader (task_gtime()) * that can thus safely catch up with a tickless delta.
@@ -776,12 +776,12 @@ void vtime_account_idle(struct task_struvoid arch_vtime_task_switch (struct task_struct *prev) {write_seqcount_begin (&prev->vtime_seqcount); - prev->vtime_snap_whence =VTIME_INACTIVE ; + prev->vtime_state =VTIME_INACTIVE ;write_seqcount_end (&prev->vtime_seqcount);write_seqcount_begin (¤t->vtime_seqcount); - current->vtime_snap_whence =VTIME_SYS ; - current->vtime_snap = jiffies; + current->vtime_state =VTIME_SYS ; + current->vtime_starttime = jiffies;write_seqcount_end (¤t->vtime_seqcount); }
@@ -791,8 +791,8 @@ void vtime_init_idle(struct task_structlocal_irq_save (flags);write_seqcount_begin (&t->vtime_seqcount); - t->vtime_snap_whence =VTIME_SYS ; - t->vtime_snap = jiffies; + t->vtime_state =VTIME_SYS ; + t->vtime_starttime = jiffies;write_seqcount_end (&t->vtime_seqcount);local_irq_restore (flags); }
@@ -809,7 +809,7 @@ u64 task_gtime(struct task_struct *t) seq =read_seqcount_begin (&t->vtime_seqcount); gtime = t->gtime; -if (t->vtime_snap_whence ==VTIME_SYS && t->flags &PF_VCPU ) +if (t->vtime_state ==VTIME_SYS && t->flags &PF_VCPU ) gtime +=vtime_delta (t); }while (read_seqcount_retry (&t->vtime_seqcount, seq));
@@ -840,7 +840,7 @@ void task_cputime(struct task_struct *t, *stime = t->stime;/* Task is sleeping, nothing to add */ -if (t->vtime_snap_whence ==VTIME_INACTIVE ||is_idle_task (t)) +if (t->vtime_state ==VTIME_INACTIVE ||is_idle_task (t))continue ; delta =vtime_delta (t);
@@ -849,9 +849,9 @@ void task_cputime(struct task_struct *t,* Task runs either in user or kernel space, add pending nohz time to * the right place. */ -if (t->vtime_snap_whence ==VTIME_USER || t->flags &PF_VCPU ) +if (t->vtime_state ==VTIME_USER || t->flags &PF_VCPU ) *utime += delta; -else if (t->vtime_snap_whence ==VTIME_SYS ) +else if (t->vtime_state ==VTIME_SYS ) *stime += delta; }while (read_seqcount_retry (&t->vtime_seqcount, seq)); }
Greg Kroah-Hartman
maintainerPATCH 177/196 sched/cputime: Move the vtime task fields to their own struct
In reply to Greg Kroah-Hartman4.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Frederic Weisbecker <[email protected]>
commit bac5b6b6b11560f323e71d0ebac4061cfe5f56c0 upstream.
We are about to add vtime accumulation fields to the task struct. Let's avoid more bloatification and gather vtime information to their own struct.
--- include/linux/init_task.h | 6 +- include/linux/sched.h | 26 ++++++---- kernel/fork.c | 6 +- kernel/sched/cputime.c | 114 ++++++++++++++++++++++++++-------------------- 4 files changed, 87 insertions(+), 65 deletions(-)
include/linux/init_task.h +3 -3
@@ -170,9 +170,9 @@ extern struct cred init_cred;#ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN # define INIT_VTIME (tsk) \ - .vtime_seqcount = SEQCNT_ZERO(tsk.vtime_seqcount), \ - .vtime_starttime = 0, \ - .vtime_state = VTIME_SYS, + .vtime.seqcount = SEQCNT_ZERO(tsk.vtime.seqcount), \ + .vtime.starttime = 0, \ + .vtime.state = VTIME_SYS,#else # define INIT_VTIME (tsk)#endif
include/linux/sched.h +16 -10
@@ -223,6 +223,21 @@ struct task_cputime {#define prof_exp stime#define sched_exp sum_exec_runtime +enum vtime_state { +/* Task is sleeping or running in a CPU with VTIME inactive: */ +VTIME_INACTIVE =0 , +/* Task runs in userspace in a CPU with VTIME active: */ +VTIME_USER , +/* Task runs in kernelspace in a CPU with VTIME active: */ +VTIME_SYS , +}; + +struct vtime { +seqcount_t seqcount; +unsigned long long starttime; +enum vtime_state state; +}; +struct sched_info {#ifdef CONFIG_SCHED_INFO /* Cumulative counters: */
@@ -670,16 +685,7 @@ struct task_struct {u64 gtime;struct prev_cputime prev_cputime;#ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN -seqcount_t vtime_seqcount; -unsigned long long vtime_starttime; -enum { -/* Task is sleeping or running in a CPU with VTIME inactive: */ -VTIME_INACTIVE =0 , -/* Task runs in userspace in a CPU with VTIME active: */ -VTIME_USER , -/* Task runs in kernelspace in a CPU with VTIME active: */ -VTIME_SYS , - } vtime_state; +struct vtime vtime;#endif #ifdef CONFIG_NO_HZ_FULL
kernel/fork.c +3 -3
@@ -1637,9 +1637,9 @@ static __latent_entropy struct task_struprev_cputime_init (&p->prev_cputime);#ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN -seqcount_init (&p->vtime_seqcount); - p->vtime_starttime =0 ; - p->vtime_state =VTIME_INACTIVE ; +seqcount_init (&p->vtime.seqcount); + p->vtime.starttime =0 ; + p->vtime.state =VTIME_INACTIVE ;#endif #if defined(SPLIT_RSS_COUNTING )
kernel/sched/cputime.c +65 -49
231 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 178/196 sched/cputime: Accumulate vtime on top of nsec clocksource
In reply to Greg Kroah-Hartman4.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wanpeng Li <[email protected]>
commit 2a42eb9594a1480b4ead9e036e06ee1290e5fa6d upstream.
Currently the cputime source used by vtime is jiffies. When we cross a context boundary and jiffies have changed since the last snapshot, the pending cputime is accounted to the switching out context.
This system works ok if the ticks are not aligned across CPUs. If they instead are aligned (ie: all fire at the same time) and the CPUs run in userspace, the jiffies change is only observed on tick exit and therefore the user cputime is accounted as system cputime. This is because the CPU that maintains timekeeping fires its tick at the same time as the others. It updates jiffies in the middle of the tick and the other CPUs see that update on IRQ exit:
CPU 0 (timekeeper) CPU 1
------------------- -------------
jiffies = N
... run in userspace for a jiffy
tick entry tick entry (sees jiffies = N)
set jiffies = N + 1
tick exit tick exit (sees jiffies = N + 1)
account 1 jiffy as stime
Fix this with using a nanosec clock source instead of jiffies. The cputime is then accumulated and flushed everytime the pending delta reaches a jiffy in order to mitigate the accounting overhead.
[ fweisbec: changelog, rebase on struct vtime, field renames, add delta
on cputime readers, keep idle vtime as-is (low overhead accounting), harmonize clock sources. ]
--- include/linux/sched.h | 3 ++ kernel/sched/cputime.c | 64 ++++++++++++++++++++++++++++++++----------------- 2 files changed, 45 insertions(+), 22 deletions(-)
include/linux/sched.h +3 -0
@@ -236,6 +236,9 @@ struct vtime {seqcount_t seqcount;unsigned long long starttime;enum vtime_state state; +u64 utime; +u64 stime; +u64 gtime; };struct sched_info {
kernel/sched/cputime.c +42 -22
145 lines not on this page · raw message
Re: [PATCH 4.12 178/196] sched/cputime: Accumulate vtime on top of nsec clocksource
I noticed relatively late and it hadn't occured on my own testing. I can send it as a separate patch but I wanted to highlight that it would affect a 4.12.4 release.
---8<---
sched/cputime: Don't use smp_processor_id() in preemptible context
commit 0e4097c3354e2f5a5ad8affd9dc7f7f7d00bb6b9 upstream
Recent kernels trigger this warning:
BUG: using smp_processor_id() in preemptible [00000000] code: 99-trinity/181 caller is debug_smp_processor_id+0x17/0x19 CPU: 0 PID: 181 Comm: 99-trinity Not tainted 4.12.0-01059-g2a42eb9 #1 Call Trace: dump_stack+0x82/0xb8 check_preemption_disabled() debug_smp_processor_id() vtime_delta() task_cputime() thread_group_cputime() thread_group_cputime_adjusted() wait_consider_task() do_wait() SYSC_wait4() do_syscall_64() entry_SYSCALL64_slow_path()
As Frederic pointed out:
| Although those sched_clock_cpu() things seem to only matter when the | sched_clock() is unstable. And that stability is a condition for nohz_full | to work anyway. So probably sched_clock() alone would be enough.
This patch fixes it by replacing sched_clock_cpu() with sched_clock() to avoid calling smp_processor_id() in a preemptible context.
kernel/sched/cputime.c +3 -3
@@ -683,7 +683,7 @@ static u64 vtime_delta(struct vtime *vtime) {unsigned long long clock; - clock =sched_clock_cpu (smp_processor_id ()); + clock =sched_clock ();if (clock < vtime->starttime)return 0 ;
@@ -814,7 +814,7 @@ void arch_vtime_task_switch(struct task_struct *prev)write_seqcount_begin (&vtime->seqcount); vtime->state =VTIME_SYS ; - vtime->starttime =sched_clock_cpu (smp_processor_id ()); + vtime->starttime =sched_clock ();write_seqcount_end (&vtime->seqcount); }
@@ -826,7 +826,7 @@ void vtime_init_idle(struct task_struct *t, int cpu)local_irq_save (flags);write_seqcount_begin (&vtime->seqcount); vtime->state =VTIME_SYS ; - vtime->starttime =sched_clock_cpu (cpu); + vtime->starttime =sched_clock ();write_seqcount_end (&vtime->seqcount);local_irq_restore (flags); }
Greg Kroah-Hartman
maintainerRe: [PATCH 4.12 178/196] sched/cputime: Accumulate vtime on top of nsec clocksource
Quoted 8 lines · Mel Gorman
I noticed relatively late and it hadn't occured on my own testing. I can send it as a separate patch but I wanted to highlight that it would affect a 4.12.4 release.
---8<---
sched/cputime: Don't usesmp_processor_id()in preemptible contextcommit
0e4097c3354e2f5a5ad8affd9dc7f7f7d00bb6b9upstream
Now queued up, thanks for letting me know.
greg k-h
Greg Kroah-Hartman
maintainerPATCH 179/196 sched/fair: Fix load_balance() affinity redo path
In reply to Greg Kroah-Hartman4.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jeffrey Hugo <[email protected]>
commit 65a4433aebe36c8c6abeb69b99ef00274b971c6c upstream.
If load_balance() fails to migrate any tasks because all tasks were affined, load_balance() removes the source CPU from consideration and attempts to redo and balance among the new subset of CPUs.
There is a bug in this code path where the algorithm considers all active CPUs in the system (minus the source that was just masked out). This is not valid for two reasons: some active CPUs may not be in the current scheduling domain and one of the active CPUs is dst_cpu. These CPUs should not be considered, as we cannot pull load from them.
Instead of failing out of load_balance(), we may end up redoing the search with no valid CPUs and incorrectly concluding the domain is balanced. Additionally, if the group_imbalance flag was just set, it may also be incorrectly unset, thus the flag will not be seen by other CPUs in future load_balance() runs as that algorithm intends.
Fix the check by removing CPUs not in the current domain and the dst_cpu from considertation, thus limiting the evaluation to valid remaining CPUs from which load might be migrated.
--- kernel/sched/fair.c | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-)
kernel/sched/fair.c +20 -12
@@ -6619,10 +6619,10 @@ int can_migrate_task(struct task_struct* our sched_group. We may want to revisit it if we couldn't * meet load balance goals by pulling other tasks on src_cpu. * -* Also avoid computing new_dst_cpu if we have already computed -* one in current iteration. +* Avoid computing new_dst_cpu for NEWLY_IDLE or if we have +* already computed one in current iteration. */ -if (!env->dst_grpmask || (env->flags &LBF_DST_PINNED )) +if (env->idle ==CPU_NEWLY_IDLE || (env->flags &LBF_DST_PINNED ))return 0 ;/* Prevent to re-select dst_cpu via env's cpus */
@@ -7973,14 +7973,7 @@ static int load_balance(int this_cpu, st .tasks = LIST_HEAD_INIT(env.tasks), }; -/* -* For NEWLY_IDLE load_balancing, we don't need to consider -* other cpus in our group -*/ -if (idle ==CPU_NEWLY_IDLE ) - env.dst_grpmask =NULL ; - -cpumask_copy (cpus, cpu_active_mask); +cpumask_and (cpus,sched_domain_span (sd), cpu_active_mask);schedstat_inc (sd->lb_count[idle]);
@@ -8102,7 +8095,15 @@ more_balance:/* All tasks on this runqueue were pinned by CPU affinity */ if (unlikely (env.flags &LBF_ALL_PINNED )) {cpumask_clear_cpu (cpu_of (busiest), cpus); -if (!cpumask_empty (cpus)) { +/* +* Attempting to continue load balancing at the current +* sched_domain level only makes sense if there are +* active CPUs remaining as possible busiest CPUs to +* pull load from which are not contained within the +* destination group that is receiving any migrated +* load. +*/ +if (!cpumask_subset (cpus, env.dst_grpmask)) { env.loop =0 ; env.loop_break = sched_nr_migrate_break; goto redo;
@@ -8398,6 +8399,13 @@ static int active_load_balance_cpu_stop( .src_cpu = busiest_rq->cpu, .src_rq = busiest_rq, .idle = CPU_IDLE, +/* +* can_migrate_task() doesn't need to compute new_dst_cpu +* for active balancing. Since we have CPU_IDLE, but no +* @dst_grpmask we need to make that test go away with lying +* about DST_PINNED. +*/ + .flags =LBF_DST_PINNED , };schedstat_inc (sd->alb_count);
Greg Kroah-Hartman
maintainerPATCH 180/196 percpu_counter: Rename __percpu_counter_add to percpu_counter_add_batch
In reply to Greg Kroah-Hartman4.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nikolay Borisov <[email protected]>
commit 104b4e5139fe384431ac11c3b8a6cf4a529edf4a upstream.
Currently, percpu_counter_add is a wrapper around __percpu_counter_add which is preempt safe due to explicit calls to preempt_disable. Given how __ prefix is used in percpu related interfaces, the naming unfortunately creates the false sense that __percpu_counter_add is less safe than percpu_counter_add. In terms of context-safety, they're equivalent. The only difference is that the __ version takes a batch parameter.
Make this a bit more explicit by just renaming __percpu_counter_add to percpu_counter_add_batch.
This patch doesn't cause any functional changes.
tj: Minor updates to patch description for clarity. Cosmetic
indentation updates.
--- fs/btrfs/disk-io.c | 12 ++++++------ fs/btrfs/extent_io.c | 6 +++--- fs/btrfs/inode.c | 8 ++++---- fs/xfs/xfs_mount.c | 4 ++-- include/linux/backing-dev.h | 2 +- include/linux/blk-cgroup.h | 6 +++--- include/linux/mman.h | 2 +- include/linux/percpu_counter.h | 7 ++++--- include/net/inet_frag.h | 4 ++-- lib/flex_proportions.c | 6 +++--- lib/percpu_counter.c | 4 ++-- 11 files changed, 31 insertions(+), 30 deletions(-)
fs/btrfs/disk-io.c +6 -6
@@ -1255,9 +1255,9 @@ void clean_tree_block(struct btrfs_fs_inbtrfs_assert_tree_locked (buf);if (test_and_clear_bit (EXTENT_BUFFER_DIRTY , &buf->bflags)) { -__percpu_counter_add (&fs_info->dirty_metadata_bytes, - -buf->len, - fs_info->dirty_metadata_batch); +percpu_counter_add_batch (&fs_info->dirty_metadata_bytes, + -buf->len, + fs_info->dirty_metadata_batch);/* ugh, clear_extent_buffer_dirty needs to lock the page */ btrfs_set_lock_blocking (buf);clear_extent_buffer_dirty (buf);
@@ -4049,9 +4049,9 @@ void btrfs_mark_buffer_dirty(struct exte buf->start, transid, fs_info->generation); was_dirty =set_extent_buffer_dirty (buf);if (!was_dirty) -__percpu_counter_add (&fs_info->dirty_metadata_bytes, - buf->len, - fs_info->dirty_metadata_batch); +percpu_counter_add_batch (&fs_info->dirty_metadata_bytes, + buf->len, + fs_info->dirty_metadata_batch);#ifdef CONFIG_BTRFS_FS_CHECK_INTEGRITY if (btrfs_header_level (buf) ==0 &&check_leaf (root, buf)) {btrfs_print_leaf (fs_info, buf);
fs/btrfs/extent_io.c +3 -3
@@ -3597,9 +3597,9 @@ lock_extent_buffer_for_io(struct extent_set_bit (EXTENT_BUFFER_WRITEBACK , &eb->bflags);spin_unlock (&eb->refs_lock);btrfs_set_header_flag (eb,BTRFS_HEADER_FLAG_WRITTEN ); -__percpu_counter_add (&fs_info->dirty_metadata_bytes, - -eb->len, - fs_info->dirty_metadata_batch); +percpu_counter_add_batch (&fs_info->dirty_metadata_bytes, + -eb->len, + fs_info->dirty_metadata_batch); ret =1 ; }else {spin_unlock (&eb->refs_lock);
fs/btrfs/inode.c +4 -4
@@ -1766,8 +1766,8 @@ static void btrfs_set_bit_hook(struct inif (btrfs_is_testing (fs_info))return ; -__percpu_counter_add (&fs_info->delalloc_bytes, len, - fs_info->delalloc_batch); +percpu_counter_add_batch (&fs_info->delalloc_bytes, len, + fs_info->delalloc_batch);spin_lock (&BTRFS_I (inode)->lock);BTRFS_I (inode)->delalloc_bytes += len;if (*bits &EXTENT_DEFRAG )
@@ -1840,8 +1840,8 @@ static void btrfs_clear_bit_hook(struct &inode->vfs_inode, state->start, len); -__percpu_counter_add (&fs_info->delalloc_bytes, -len, - fs_info->delalloc_batch); +percpu_counter_add_batch (&fs_info->delalloc_bytes, -len, + fs_info->delalloc_batch);spin_lock (&inode->lock); inode->delalloc_bytes -= len; if (do_list && inode->delalloc_bytes == 0 &&
fs/xfs/xfs_mount.c +2 -2
@@ -1209,7 +1209,7 @@ xfs_mod_icount( struct xfs_mount *mp, int64_t delta) { -__percpu_counter_add (&mp->m_icount, delta,XFS_ICOUNT_BATCH ); +percpu_counter_add_batch (&mp->m_icount, delta,XFS_ICOUNT_BATCH );if (__percpu_counter_compare (&mp->m_icount,0 ,XFS_ICOUNT_BATCH ) <0 ) {ASSERT (0 );percpu_counter_add (&mp->m_icount, -delta);
@@ -1288,7 +1288,7 @@ xfs_mod_fdblocks(else batch =XFS_FDBLOCKS_BATCH ; -__percpu_counter_add (&mp->m_fdblocks, delta, batch); +percpu_counter_add_batch (&mp->m_fdblocks, delta, batch);if (__percpu_counter_compare (&mp->m_fdblocks, mp->m_alloc_set_aside,XFS_FDBLOCKS_BATCH ) >=0 ) {/* we had space! */
include/linux/backing-dev.h +1 -1
@@ -66,7 +66,7 @@ static inline bool bdi_has_dirty_io(strustatic inline void __add_wb_stat (struct bdi_writeback *wb,enum wb_stat_item item,s64 amount) { -__percpu_counter_add (&wb->stat[item], amount,WB_STAT_BATCH ); +percpu_counter_add_batch (&wb->stat[item], amount,WB_STAT_BATCH ); } static inline void __inc_wb_stat(struct bdi_writeback *wb,
include/linux/blk-cgroup.h +3 -3
@@ -518,7 +518,7 @@ static inline void blkg_stat_exit(struct*/ static inline void blkg_stat_add (struct blkg_stat *stat,uint64_t val) { -__percpu_counter_add (&stat->cpu_cnt, val,BLKG_STAT_CPU_BATCH ); +percpu_counter_add_batch (&stat->cpu_cnt, val,BLKG_STAT_CPU_BATCH ); }/**
@@ -597,14 +597,14 @@ static inline void blkg_rwstat_add(strucelse cnt = &rwstat->cpu_cnt[BLKG_RWSTAT_READ ]; -__percpu_counter_add (cnt, val,BLKG_STAT_CPU_BATCH ); +percpu_counter_add_batch (cnt, val,BLKG_STAT_CPU_BATCH );if (op_is_sync (op)) cnt = &rwstat->cpu_cnt[BLKG_RWSTAT_SYNC ];else cnt = &rwstat->cpu_cnt[BLKG_RWSTAT_ASYNC ]; -__percpu_counter_add (cnt, val,BLKG_STAT_CPU_BATCH ); +percpu_counter_add_batch (cnt, val,BLKG_STAT_CPU_BATCH ); }/**
include/linux/mman.h +1 -1
@@ -22,7 +22,7 @@ unsigned long vm_memory_committed(void);static inline void vm_acct_memory (long pages) { -__percpu_counter_add (&vm_committed_as, pages, vm_committed_as_batch); +percpu_counter_add_batch (&vm_committed_as, pages, vm_committed_as_batch); }static inline void vm_unacct_memory (long pages)
include/linux/percpu_counter.h +4 -3
@@ -39,7 +39,8 @@ int __percpu_counter_init(struct percpu_void percpu_counter_destroy (struct percpu_counter *fbc);void percpu_counter_set (struct percpu_counter *fbc,s64 amount); -void __percpu_counter_add (struct percpu_counter *fbc,s64 amount,s32 batch); +void percpu_counter_add_batch (struct percpu_counter *fbc,s64 amount, +s32 batch);s64 __percpu_counter_sum (struct percpu_counter *fbc);int __percpu_counter_compare (struct percpu_counter *fbc,s64 rhs,s32 batch);
@@ -50,7 +51,7 @@ static inline int percpu_counter_comparestatic inline void percpu_counter_add (struct percpu_counter *fbc,s64 amount) { -__percpu_counter_add (fbc, amount, percpu_counter_batch); +percpu_counter_add_batch (fbc, amount, percpu_counter_batch); }static inline s64 percpu_counter_sum_positive (struct percpu_counter *fbc)
@@ -136,7 +137,7 @@ percpu_counter_add(struct percpu_counter }static inline void -__percpu_counter_add (struct percpu_counter *fbc,s64 amount,s32 batch) +percpu_counter_add_batch (struct percpu_counter *fbc,s64 amount,s32 batch) {percpu_counter_add (fbc, amount); }
include/net/inet_frag.h +2 -2
@@ -154,12 +154,12 @@ static inline int frag_mem_limit(structstatic inline void sub_frag_mem_limit (struct netns_frags *nf,int i) { -__percpu_counter_add (&nf->mem, -i, frag_percpu_counter_batch); +percpu_counter_add_batch (&nf->mem, -i, frag_percpu_counter_batch); }static inline void add_frag_mem_limit (struct netns_frags *nf,int i) { -__percpu_counter_add (&nf->mem, i, frag_percpu_counter_batch); +percpu_counter_add_batch (&nf->mem, i, frag_percpu_counter_batch); }static inline unsigned int sum_frag_mem_limit (struct netns_frags *nf)
lib/flex_proportions.c +3 -3
@@ -207,7 +207,7 @@ static void fprop_reflect_period_percpu(if (val < (nr_cpu_ids *PROP_BATCH )) val =percpu_counter_sum (&pl->events); -__percpu_counter_add (&pl->events, +percpu_counter_add_batch (&pl->events, -val + (val >> (period-pl->period)),PROP_BATCH ); }else percpu_counter_set (&pl->events,0 );
@@ -219,7 +219,7 @@ static void fprop_reflect_period_percpu(void __fprop_inc_percpu (struct fprop_global *p,struct fprop_local_percpu *pl) {fprop_reflect_period_percpu (p, pl); -__percpu_counter_add (&pl->events,1 ,PROP_BATCH ); +percpu_counter_add_batch (&pl->events,1 ,PROP_BATCH );percpu_counter_add (&p->events,1 ); }
@@ -267,6 +267,6 @@ void __fprop_inc_percpu_max(struct fpropreturn ; }else fprop_reflect_period_percpu (p, pl); -__percpu_counter_add (&pl->events,1 ,PROP_BATCH ); +percpu_counter_add_batch (&pl->events,1 ,PROP_BATCH );percpu_counter_add (&p->events,1 ); }
lib/percpu_counter.c +2 -2
@@ -72,7 +72,7 @@ void percpu_counter_set(struct percpu_co }EXPORT_SYMBOL (percpu_counter_set); -void __percpu_counter_add (struct percpu_counter *fbc,s64 amount,s32 batch) +void percpu_counter_add_batch (struct percpu_counter *fbc,s64 amount,s32 batch) {s64 count;
@@ -89,7 +89,7 @@ void __percpu_counter_add(struct percpu_ }preempt_enable (); } -EXPORT_SYMBOL (__percpu_counter_add); +EXPORT_SYMBOL (percpu_counter_add_batch);/* * Add up all the per-cpu counts, return the result. This is a more accurate
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Greg Kroah-Hartman
maintainerPATCH 181/196 writeback: rework wb_[dec|inc]_stat family of functions
In reply to Greg Kroah-Hartman4.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nikolay Borisov <[email protected]>
commit 3e8f399da490e6ac20a3cfd6aa404c9aa961a9a2 upstream.
Currently the writeback statistics code uses a percpu counters to hold various statistics. Furthermore we have 2 families of functions - those which disable local irq and those which doesn't and whose names begin with double underscore. However, they both end up calling __add_wb_stats which in turn calls percpu_counter_add_batch which is already irq-safe.
Exploiting this fact allows to eliminated the __wb_* functions since they don't add any further protection than we already have. Furthermore, refactor the wb_* function to call __add_wb_stat directly without the irq-disabling dance. This will likely result in better runtime of code which deals with modifying the stat counters.
While at it also document why percpu_counter_add_batch is in fact preempt and irq-safe since at least 3 people got confused.
--- fs/fs-writeback.c | 8 ++++---- include/linux/backing-dev.h | 24 ++---------------------- lib/percpu_counter.c | 7 +++++++ mm/page-writeback.c | 10 +++++----- 4 files changed, 18 insertions(+), 31 deletions(-)
fs/fs-writeback.c +4 -4
@@ -380,8 +380,8 @@ static void inode_switch_wbs_work_fn(strstruct page *page =radix_tree_deref_slot_protected (slot, &mapping->tree_lock);if (likely (page) &&PageDirty (page)) { -__dec_wb_stat (old_wb,WB_RECLAIMABLE ); -__inc_wb_stat (new_wb,WB_RECLAIMABLE ); +dec_wb_stat (old_wb,WB_RECLAIMABLE ); +inc_wb_stat (new_wb,WB_RECLAIMABLE ); } }
@@ -391,8 +391,8 @@ static void inode_switch_wbs_work_fn(str &mapping->tree_lock);if (likely (page)) {WARN_ON_ONCE (!PageWriteback (page)); -__dec_wb_stat (old_wb,WB_WRITEBACK ); -__inc_wb_stat (new_wb,WB_WRITEBACK ); +dec_wb_stat (old_wb,WB_WRITEBACK ); +inc_wb_stat (new_wb,WB_WRITEBACK ); } }
include/linux/backing-dev.h +2 -22
@@ -69,34 +69,14 @@ static inline void __add_wb_stat(structpercpu_counter_add_batch (&wb->stat[item], amount,WB_STAT_BATCH ); } -static inline void __inc_wb_stat (struct bdi_writeback *wb, -enum wb_stat_item item) -{ -__add_wb_stat (wb, item,1 ); -} -static inline void inc_wb_stat (struct bdi_writeback *wb,enum wb_stat_item item) { -unsigned long flags; - -local_irq_save (flags); -__inc_wb_stat (wb, item); -local_irq_restore (flags); -} - -static inline void __dec_wb_stat (struct bdi_writeback *wb, -enum wb_stat_item item) -{ -__add_wb_stat (wb, item,-1 ); +__add_wb_stat (wb, item,1 ); }static inline void dec_wb_stat (struct bdi_writeback *wb,enum wb_stat_item item) { -unsigned long flags; - -local_irq_save (flags); -__dec_wb_stat (wb, item); -local_irq_restore (flags); +__add_wb_stat (wb, item,-1 ); }static inline s64 wb_stat (struct bdi_writeback *wb,enum wb_stat_item item)
lib/percpu_counter.c +7 -0
@@ -72,6 +72,13 @@ void percpu_counter_set(struct percpu_co }EXPORT_SYMBOL (percpu_counter_set); +/** +* This function is both preempt and irq safe. The former is due to explicit +* preemption disable. The latter is guaranteed by the fact that the slow path +* is explicitly protected by an irq-safe spinlock whereas the fast patch uses +* this_cpu_add which is irq-safe by definition. Hence there is no need muck +* with irq state before calling this one +*/ void percpu_counter_add_batch (struct percpu_counter *fbc,s64 amount,s32 batch) {s64 count;
mm/page-writeback.c +5 -5
@@ -601,7 +601,7 @@ static inline void __wb_writeout_inc(str {struct wb_domain *cgdom; -__inc_wb_stat (wb,WB_WRITTEN ); +inc_wb_stat (wb,WB_WRITTEN );wb_domain_writeout_inc (&global_wb_domain, &wb->completions, wb->bdi->max_prop_frac);
@@ -2437,8 +2437,8 @@ void account_page_dirtied(struct page *p__inc_node_page_state (page,NR_FILE_DIRTY );__inc_zone_page_state (page,NR_ZONE_WRITE_PENDING );__inc_node_page_state (page,NR_DIRTIED ); -__inc_wb_stat (wb,WB_RECLAIMABLE ); -__inc_wb_stat (wb,WB_DIRTIED ); +inc_wb_stat (wb,WB_RECLAIMABLE ); +inc_wb_stat (wb,WB_DIRTIED );task_io_account_write (PAGE_SIZE ); current->nr_dirtied++;this_cpu_inc (bdp_ratelimits);
@@ -2745,7 +2745,7 @@ int test_clear_page_writeback(struct pagif (bdi_cap_account_writeback (bdi)) {struct bdi_writeback *wb =inode_to_wb (inode); -__dec_wb_stat (wb,WB_WRITEBACK ); +dec_wb_stat (wb,WB_WRITEBACK );__wb_writeout_inc (wb); } }
@@ -2791,7 +2791,7 @@ int __test_set_page_writeback(struct pagpage_index (page), PAGECACHE_TAG_WRITEBACK);if (bdi_cap_account_writeback (bdi)) -__inc_wb_stat (inode_to_wb (inode),WB_WRITEBACK ); +inc_wb_stat (inode_to_wb (inode),WB_WRITEBACK );/* * We can come through here when swapping anonymous
Greg Kroah-Hartman
maintainerPATCH 182/196 kernel/fork.c: virtually mapped stacks: do not disable interrupts
In reply to Greg Kroah-Hartman4.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christoph Lameter <[email protected]>
commit 112166f88cf83dd11486cf1818672d42b540865b upstream.
The reason to disable interrupts seems to be to avoid switching to a different processor while handling per cpu data using individual loads and stores. If we use per cpu RMV primitives we will not have to disable interrupts.
--- kernel/fork.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-)
kernel/fork.c +5 -11
@@ -205,19 +205,17 @@ static unsigned long *alloc_thread_stackvoid *stack;int i; -local_irq_disable ();for (i =0 ; i <NR_CACHED_STACKS ; i++) { -struct vm_struct *s =this_cpu_read (cached_stacks[i]); +struct vm_struct *s; + + s =this_cpu_xchg (cached_stacks[i],NULL );if (!s)continue ; -this_cpu_write (cached_stacks[i],NULL ); tsk->stack_vm_area = s; -local_irq_enable ();return s->addr; } -local_irq_enable (); stack = __vmalloc_node_range(THREAD_SIZE, THREAD_SIZE, VMALLOC_START, VMALLOC_END,
@@ -245,19 +243,15 @@ static inline void free_thread_stack(str {#ifdef CONFIG_VMAP_STACK if (task_stack_vm_area (tsk)) { -unsigned long flags;int i; -local_irq_save (flags);for (i =0 ; i <NR_CACHED_STACKS ; i++) { -if (this_cpu_read (cached_stacks[i])) +if (this_cpu_cmpxchg (cached_stacks[i], +NULL , tsk->stack_vm_area) !=NULL )continue ; -this_cpu_write (cached_stacks[i], tsk->stack_vm_area); -local_irq_restore (flags);return ; } -local_irq_restore (flags);vfree_atomic (tsk->stack);return ;
Greg Kroah-Hartman
maintainerPATCH 183/196 acpi/nfit: Fix memory corruption/Unregister mce decoder on failure
In reply to Greg Kroah-Hartman4.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Prarit Bhargava <[email protected]>
commit 7e700d2c59e5853c9126642976b4f5768f64c9b3 upstream.
nfit_init() calls nfit_mce_register() on module load. When the module load fails the nfit mce decoder is not unregistered. The module's memory is freed leaving the decoder chain referencing junk. This will cause panics as future registrations will reference the free'd memory.
Unregister the nfit mce decoder on module init failure.
[v2]: register and then unregister mce handler to avoid losing mce events [v3]: also cleanup nfit workqueue
--- drivers/acpi/nfit/core.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
drivers/acpi/nfit/core.c +9 -1
@@ -3043,6 +3043,8 @@ static struct acpi_driver acpi_nfit_drivstatic __init int nfit_init (void ) { +int ret; +BUILD_BUG_ON (sizeof (struct acpi_table_nfit ) !=40 );BUILD_BUG_ON (sizeof (struct acpi_nfit_system_address ) !=56 );BUILD_BUG_ON (sizeof (struct acpi_nfit_memory_map ) !=48 );
@@ -3070,8 +3072,14 @@ static __init int nfit_init(void)return -ENOMEM ;nfit_mce_register (); + ret =acpi_bus_register_driver (&acpi_nfit_driver); +if (ret) { +nfit_mce_unregister (); +destroy_workqueue (nfit_wq); + } + +return ret; -return acpi_bus_register_driver (&acpi_nfit_driver); } static __exit void nfit_exit(void)
Greg Kroah-Hartman
maintainerPATCH 184/196 vmbus: re-enable channel tasklet
In reply to Greg Kroah-Hartman4.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stephen Hemminger <[email protected]>
commit 6463a4571ceefc43908df4b016d8d5d8b8e85357 upstream.
This problem shows up in 4.11 when netvsc driver is removed and reloaded. The problem is that the channel is closed during module removal and the tasklet for processing responses is disabled. When module is reloaded the channel is reopened but the tasklet is marked as disabled. The fix is to re-enable tasklet at the end of close which gets it back to the initial state.
The issue is less urgent in 4.12 since network driver now uses NAPI and not the tasklet; and other VMBUS devices are rarely unloaded/reloaded.
--- drivers/hv/channel.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/hv/channel.c +2 -0
@@ -606,6 +606,8 @@ static int vmbus_close_internal(struct v get_order(channel->ringbuffer_pagecount * PAGE_SIZE)); out: +/* re-enable tasklet for use on re-open */ +tasklet_enable (&channel->callback_event);return ret; }
Greg Kroah-Hartman
maintainerPATCH 185/196 cpufreq: intel_pstate: Correct the busy calculation for KNL
In reply to Greg Kroah-Hartman4.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Srinivas Pandruvada <[email protected]>
commit 6e34e1f23d780978da65968327cbba6d7013a73f upstream.
The busy percent calculated for the Knights Landing (KNL) platform is 1024 times smaller than the correct busy value. This causes performance to get stuck at the lowest ratio.
The scaling algorithm used for KNL is performance-based, but it still looks at the CPU load to set the scaled busy factor to 0 when the load is less than 1 percent. In this case, since the computed load is 1024x smaller than it should be, the scaled busy factor will always be 0, irrespective of CPU business.
This needs a fix similar to the turbostat one in commit b2b34dfe4d9a (tools/power turbostat: KNL workaround for %Busy and Avg_MHz).
For this reason, add one more callback to processor-specific callbacks to specify an MPERF multiplier represented by a number of bit positions to shift the value of that register to the left to copmensate for its rate difference with respect to the TSC. This shift value is used during CPU busy calculations.
--- drivers/cpufreq/intel_pstate.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-)
drivers/cpufreq/intel_pstate.c +19 -2
@@ -225,6 +225,9 @@ struct global_params {* @vid: Stores VID limits for this CPU * @pid: Stores PID parameters for this CPU * @last_sample_time: Last Sample time +* @aperf_mperf_shift: Number of clock cycles after aperf, merf is incremented +* This shift is a multiplier to mperf delta to +* calculate CPU busy. * @prev_aperf: Last APERF value read from APERF MSR * @prev_mperf: Last MPERF value read from MPERF MSR * @prev_tsc: Last timestamp counter (TSC) value
@@ -261,6 +264,7 @@ struct cpudata {u64 last_update;u64 last_sample_time; +u64 aperf_mperf_shift;u64 prev_aperf;u64 prev_mperf;u64 prev_tsc;
@@ -323,6 +327,7 @@ struct pstate_funcs {int (*get_min)(void );int (*get_turbo)(void );int (*get_scaling)(void ); +int (*get_aperf_mperf_shift)(void );u64 (*get_val)(struct cpudata *,int pstate);void (*get_vid)(struct cpudata *); void (*update_util)(struct update_util_data *data, u64 time,
@@ -1485,6 +1490,11 @@ static u64 core_get_val(struct cpudata *return val; } +static int knl_get_aperf_mperf_shift (void ) +{ +return 10 ; +} +static int knl_get_turbo_pstate (void ) {u64 value;
@@ -1543,6 +1553,9 @@ static void intel_pstate_get_cpu_pstates cpu->pstate.max_freq = cpu->pstate.max_pstate * cpu->pstate.scaling; cpu->pstate.turbo_freq = cpu->pstate.turbo_pstate * cpu->pstate.scaling; +if (pstate_funcs.get_aperf_mperf_shift) + cpu->aperf_mperf_shift = pstate_funcs.get_aperf_mperf_shift (); +if (pstate_funcs.get_vid) pstate_funcs.get_vid (cpu);
@@ -1619,7 +1632,8 @@ static inline int32_t get_target_pstate_if (cpu->policy ==CPUFREQ_POLICY_PERFORMANCE )return cpu->pstate.turbo_pstate; - busy_frac =div_fp (sample->mperf, sample->tsc); + busy_frac =div_fp (sample->mperf << cpu->aperf_mperf_shift, + sample->tsc); boost = cpu->iowait_boost; cpu->iowait_boost >>=1 ;
@@ -1681,7 +1695,8 @@ static inline int32_t get_target_pstate_ sample_ratio =div_fp (pid_params.sample_rate_ns, duration_ns); perf_scaled =mul_fp (perf_scaled, sample_ratio); }else { - sample_ratio =div_fp (100 * cpu->sample.mperf, cpu->sample.tsc); + sample_ratio =div_fp (100 * (cpu->sample.mperf << cpu->aperf_mperf_shift), + cpu->sample.tsc);if (sample_ratio <int_tofp (1 )) perf_scaled =0 ; }
@@ -1824,6 +1839,7 @@ static const struct pstate_funcs knl_fun .get_max_physical = core_get_max_pstate_physical, .get_min = core_get_min_pstate, .get_turbo = knl_get_turbo_pstate, + .get_aperf_mperf_shift = knl_get_aperf_mperf_shift, .get_scaling = core_get_scaling, .get_val = core_get_val, .update_util = intel_pstate_update_util_pid,
@@ -2408,6 +2424,7 @@ static void __init copy_cpu_funcs(struct pstate_funcs.get_val = funcs->get_val; pstate_funcs.get_vid = funcs->get_vid; pstate_funcs.update_util = funcs->update_util; + pstate_funcs.get_aperf_mperf_shift = funcs->get_aperf_mperf_shift;intel_pstate_use_acpi_profile (); }
Greg Kroah-Hartman
maintainerPATCH 186/196 spmi: Include OF based modalias in device uevent
In reply to Greg Kroah-Hartman4.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bjorn Andersson <[email protected]>
commit d50daa2af2618dab6d21634e65a5fbcf4ae437d6 upstream.
Include the OF-based modalias in the uevent sent when registering SPMI devices, so that user space has a chance to autoload the kernel module for the device.
--- drivers/spmi/spmi.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
drivers/spmi/spmi.c +12 -0
@@ -365,11 +365,23 @@ static int spmi_drv_remove(struct devicereturn 0 ; } +static int spmi_drv_uevent (struct device *dev,struct kobj_uevent_env *env) +{ +int ret; + + ret =of_device_uevent_modalias (dev, env); +if (ret != -ENODEV ) +return ret; + +return 0 ; +} +static struct bus_type spmi_bus_type = { .name ="spmi" , .match = spmi_device_match, .probe = spmi_drv_probe, .remove = spmi_drv_remove, + .uevent = spmi_drv_uevent, };/**
Greg Kroah-Hartman
maintainerPATCH 187/196 reiserfs: Dont clear SGID when inheriting ACLs
In reply to Greg Kroah-Hartman4.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jan Kara <[email protected]>
commit 6883cd7f68245e43e91e5ee583b7550abf14523f upstream.
When new directory 'DIR1' is created in a directory 'DIR0' with SGID bit set, DIR1 is expected to have SGID bit set (and owning group equal to the owning group of 'DIR0'). However when 'DIR0' also has some default ACLs that 'DIR1' inherits, setting these ACLs will result in SGID bit on 'DIR1' to get cleared if user is not member of the owning group.
Fix the problem by moving posix_acl_update_mode() out of __reiserfs_set_acl() into reiserfs_set_acl(). That way the function will not be called when inheriting ACLs which is what we want as it prevents SGID bit clearing and the mode has been properly set by posix_acl_create() anyway.
--- fs/reiserfs/xattr_acl.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
fs/reiserfs/xattr_acl.c +7 -5
@@ -37,7 +37,14 @@ reiserfs_set_acl(struct inode *inode, st error =journal_begin (&th, inode->i_sb, jcreate_blocks);reiserfs_write_unlock (inode->i_sb);if (error ==0 ) { +if (type ==ACL_TYPE_ACCESS && acl) { + error =posix_acl_update_mode (inode, &inode->i_mode, + &acl); +if (error) + goto unlock; + } error =__reiserfs_set_acl (&th, inode, type, acl); +unlock:reiserfs_write_lock (inode->i_sb); error2 =journal_end (&th);reiserfs_write_unlock (inode->i_sb);
@@ -241,11 +248,6 @@ __reiserfs_set_acl(struct reiserfs_transswitch (type) {case ACL_TYPE_ACCESS : name =XATTR_NAME_POSIX_ACL_ACCESS ; -if (acl) { - error =posix_acl_update_mode (inode, &inode->i_mode, &acl); -if (error) -return error; - }break ;case ACL_TYPE_DEFAULT : name =XATTR_NAME_POSIX_ACL_DEFAULT ;
Greg Kroah-Hartman
maintainerPATCH 188/196 device-dax: fix sysfs duplicate warnings
In reply to Greg Kroah-Hartman4.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Williams <[email protected]>
commit bbb3be170ac2891526ad07b18af7db226879a8e7 upstream.
Fix warnings of the form...
WARNING: CPU: 10 PID: 4983 at fs/sysfs/dir.c:31 sysfs_warn_dup+0x62/0x80
sysfs: cannot create duplicate filename '/class/dax/dax12.0'
Call Trace:
dump_stack+0x63/0x86
__warn+0xcb/0xf0
warn_slowpath_fmt+0x5a/0x80
? kernfs_path_from_node+0x4f/0x60
sysfs_warn_dup+0x62/0x80
sysfs_do_create_link_sd.isra.2+0x97/0xb0
sysfs_create_link+0x25/0x40
device_add+0x266/0x630
devm_create_dax_dev+0x2cf/0x340 [dax]
dax_pmem_probe+0x1f5/0x26e [dax_pmem]
nvdimm_bus_probe+0x71/0x120...by reusing the namespace id for the device-dax instance name.
Now that we have decided that there will never by more than one device-dax instance per libnvdimm-namespace parent device [1], we can directly reuse the namepace ids. There are some possible follow-on cleanups, but those are saved for a later patch to simplify the -stable backport.
[1]: https://lists.01.org/pipermail/linux-nvdimm/2016-December/008266.html
--- drivers/dax/device-dax.h | 2 +- drivers/dax/device.c | 24 ++++++++++++++++-------- drivers/dax/pmem.c | 12 +++++++----- 3 files changed, 24 insertions(+), 14 deletions(-)
drivers/dax/device-dax.h +1 -1
@@ -21,5 +21,5 @@ struct dax_region *alloc_dax_region(stru int region_id, struct resource *res, unsigned int align, void *addr, unsigned long flags);struct dev_dax *devm_create_dev_dax (struct dax_region *dax_region, -struct resource *res,int count); +int id,struct resource *res,int count);#endif /* __DEVICE_DAX_H__ */
drivers/dax/device.c +16 -8
@@ -528,7 +528,8 @@ static void dev_dax_release(struct devicstruct dax_region *dax_region = dev_dax->region;struct dax_device *dax_dev = dev_dax->dax_dev; -ida_simple_remove (&dax_region->ida, dev_dax->id); +if (dev_dax->id >=0 ) +ida_simple_remove (&dax_region->ida, dev_dax->id);dax_region_put (dax_region);put_dax (dax_dev);kfree (dev_dax);
@@ -558,7 +559,7 @@ static void unregister_dev_dax(void *dev }struct dev_dax *devm_create_dev_dax (struct dax_region *dax_region, -struct resource *res,int count) +int id,struct resource *res,int count) {struct device *parent = dax_region->dev;struct dax_device *dax_dev;
@@ -586,10 +587,16 @@ struct dev_dax *devm_create_dev_dax(struif (i < count) goto err_id; - dev_dax->id =ida_simple_get (&dax_region->ida,0 ,0 ,GFP_KERNEL ); -if (dev_dax->id <0 ) { - rc = dev_dax->id; - goto err_id; +if (id <0 ) { + id =ida_simple_get (&dax_region->ida,0 ,0 ,GFP_KERNEL ); + dev_dax->id = id; +if (id <0 ) { + rc = id; + goto err_id; + } + }else { +/* region provider owns @id lifetime */ + dev_dax->id =-1 ; }/*
@@ -619,7 +626,7 @@ struct dev_dax *devm_create_dev_dax(stru dev->parent = parent; dev->groups = dax_attribute_groups; dev->release = dev_dax_release; -dev_set_name (dev,"dax%d.%d" , dax_region->id, dev_dax->id); +dev_set_name (dev,"dax%d.%d" , dax_region->id, id); rc =cdev_device_add (cdev, dev);if (rc) {
@@ -635,7 +642,8 @@ struct dev_dax *devm_create_dev_dax(strureturn dev_dax; err_dax: -ida_simple_remove (&dax_region->ida, dev_dax->id); +if (dev_dax->id >=0 ) +ida_simple_remove (&dax_region->ida, dev_dax->id); err_id:kfree (dev_dax);
drivers/dax/pmem.c +7 -5
@@ -58,13 +58,12 @@ static void dax_pmem_percpu_kill(void *dstatic int dax_pmem_probe (struct device *dev) { -int rc;void *addr;struct resource res; +int rc, id, region_id;struct nd_pfn_sb *pfn_sb;struct dev_dax *dev_dax;struct dax_pmem *dax_pmem; -struct nd_region *nd_region;struct nd_namespace_io *nsio;struct dax_region *dax_region;struct nd_namespace_common *ndns;
@@ -123,14 +122,17 @@ static int dax_pmem_probe(struct device/* adjust the dax_region resource to the start of data */ res.start +=le64_to_cpu (pfn_sb->dataoff); - nd_region =to_nd_region (dev->parent); - dax_region =alloc_dax_region (dev, nd_region->id, &res, + rc =sscanf (dev_name (&ndns->dev),"namespace%d.%d" , ®ion_id, &id); +if (rc !=2 ) +return -EINVAL ; + + dax_region =alloc_dax_region (dev, region_id, &res,le32_to_cpu (pfn_sb->align), addr,PFN_DEV |PFN_MAP );if (!dax_region)return -ENOMEM ;/* TODO: support for subdividing a dax region... */ - dev_dax =devm_create_dev_dax (dax_region, &res,1 ); + dev_dax =devm_create_dev_dax (dax_region, id, &res,1 );/* child dev_dax instances now own the lifetime of the dax_region */ dax_region_put (dax_region);
Greg Kroah-Hartman
maintainerPATCH 189/196 drm/imx: parallel-display: Accept drm_of_find_panel_or_bridge failure
In reply to Greg Kroah-Hartman4.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Philipp Zabel <[email protected]>
commit 799ee2970485dc206c3bf347d6e6827c04d5e4f9 upstream.
The parallel panel driver should continue to work without having an endpoint linking to an panel in DT for backwards compatibility. With the recent switch to drm_of_find_panel_or_bridge, an absent panel results in a failure with -ENODEV error return code. To restore the old behaviour, ignore the -ENODEV return code.
--- drivers/gpu/drm/imx/parallel-display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/imx/parallel-display.c +1 -1
@@ -237,7 +237,7 @@ static int imx_pd_bind(struct device *de/* port@1 is the output port */ ret =drm_of_find_panel_or_bridge (np,1 ,0 , &imxpd->panel, &imxpd->bridge); -if (ret) +if (ret && ret != -ENODEV )return ret; imxpd->dev = dev;
Greg Kroah-Hartman
maintainerPATCH 190/196 PM / Domains: defer dev_pm_domain_set() until genpd->attach_dev succeeds if present
In reply to Greg Kroah-Hartman4.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sudeep Holla <[email protected]>
commit 975e83cfb8dc16e7a2fdc58188c77c0c605876c2 upstream.
If the genpd->attach_dev or genpd->power_on fails, genpd_dev_pm_attach may return -EPROBE_DEFER initially. However genpd_alloc_dev_data sets the PM domain for the device unconditionally.
When subsequent attempts are made to call genpd_dev_pm_attach, it may return -EEXISTS checking dev->pm_domain without re-attempting to call attach_dev or power_on.
platform_drv_probe then attempts to call drv->probe as the return value -EEXIST != -EPROBE_DEFER, which may end up in a situation where the device is accessed without it's power domain switched on.
--- drivers/base/power/domain.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/base/power/domain.c +4 -4
@@ -1168,8 +1168,6 @@ static struct generic_pm_domain_data *gespin_unlock_irq (&dev->power.lock); -dev_pm_domain_set (dev, &genpd->domain); -return gpd_data; err_free:
@@ -1183,8 +1181,6 @@ static struct generic_pm_domain_data *gestatic void genpd_free_dev_data (struct device *dev,struct generic_pm_domain_data *gpd_data) { -dev_pm_domain_set (dev,NULL ); -spin_lock_irq (&dev->power.lock); dev->power.subsys_data->domain_data =NULL ;
@@ -1221,6 +1217,8 @@ static int genpd_add_device(struct generif (ret) goto out; +dev_pm_domain_set (dev, &genpd->domain); + genpd->device_count++; genpd->max_off_time_changed = true;
@@ -1282,6 +1280,8 @@ static int genpd_remove_device(struct geif (genpd->detach_dev) genpd->detach_dev (genpd, dev); +dev_pm_domain_set (dev,NULL ); +list_del_init (&pdd->list_node);genpd_unlock (genpd);
Greg Kroah-Hartman
maintainerPATCH 191/196 tracing: Fix kmemleak in instance_rmdir
In reply to Greg Kroah-Hartman4.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chunyu Hu <[email protected]>
commit db9108e054700c96322b0f0028546aa4e643cf0b upstream.
Hit the kmemleak when executing instance_rmdir, it forgot releasing mem of tracing_cpumask. With this fix, the warn does not appear any more.
unreferenced object 0xffff93a8dfaa7c18 (size 8):
comm "mkdir", pid 1436, jiffies 4294763622 (age 9134.308s) hex dump (first 8 bytes):
ff ff ff ff ff ff ff ff ........
backtrace:
[<ffffffff88b6567a>] kmemleak_alloc+0x4a/0xa0
[<ffffffff8861ea41>] __kmalloc_node+0xf1/0x280
[<ffffffff88b505d3>] alloc_cpumask_var_node+0x23/0x30
[<ffffffff88b5060e>] alloc_cpumask_var+0xe/0x10
[<ffffffff88571ab0>] instance_mkdir+0x90/0x240
[<ffffffff886e5100>] tracefs_syscall_mkdir+0x40/0x70
[<ffffffff886565c9>] vfs_mkdir+0x109/0x1b0
[<ffffffff8865b1d0>] SyS_mkdir+0xd0/0x100
[<ffffffff88403857>] do_syscall_64+0x67/0x150
[<ffffffff88b710e7>] return_from_SYSCALL_64+0x0/0x6a
[<ffffffffffffffff>] 0xffffffffffffffff--- kernel/trace/trace.c | 1 + 1 file changed, 1 insertion(+)
kernel/trace/trace.c +1 -0
@@ -7594,6 +7594,7 @@ static int instance_rmdir(const char *na }kfree (tr->topts); +free_cpumask_var (tr->tracing_cpumask);kfree (tr->name);kfree (tr);
Greg Kroah-Hartman
maintainerPATCH 192/196 drm/i915/fbdev: Check for existence of ifbdev->vma before operations
In reply to Greg Kroah-Hartman4.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chris Wilson <[email protected]>
commit 7581d5ca2bb269cfc2ce2d0cb489aac513167f6b upstream.
Commit fabef825626d ("drm/i915: Drop struct_mutex around frontbuffer flushes") adds a dependency to ifbdev->vma when flushing the framebufer, but the checks are only against the existence of the ifbdev->fb and not against ifbdev->vma. This leaves a window of opportunity where we may try to operate on the fbdev prior to it being probed (thanks to asynchronous booting).
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=101534
--- drivers/gpu/drm/i915/intel_fbdev.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
drivers/gpu/drm/i915/intel_fbdev.c +6 -5
@@ -535,13 +535,14 @@ static void intel_fbdev_destroy(struct idrm_fb_helper_fini (&ifbdev->helper); -if (ifbdev->fb) { +if (ifbdev->vma) {mutex_lock (&ifbdev->helper.dev->struct_mutex);intel_unpin_fb_vma (ifbdev->vma);mutex_unlock (&ifbdev->helper.dev->struct_mutex); + } +if (ifbdev->fb)drm_framebuffer_remove (&ifbdev->fb->base); - }kfree (ifbdev); }
@@ -765,7 +766,7 @@ void intel_fbdev_set_suspend(struct drm_struct intel_fbdev *ifbdev = dev_priv->fbdev;struct fb_info *info; -if (!ifbdev || !ifbdev->fb) +if (!ifbdev || !ifbdev->vma)return ; info = ifbdev->helper.fbdev;
@@ -812,7 +813,7 @@ void intel_fbdev_output_poll_changed(str {struct intel_fbdev *ifbdev =to_i915 (dev)->fbdev; -if (ifbdev && ifbdev->fb) +if (ifbdev && ifbdev->vma)drm_fb_helper_hotplug_event (&ifbdev->helper); }
@@ -824,7 +825,7 @@ void intel_fbdev_restore_mode(struct drmreturn ;intel_fbdev_sync (ifbdev); -if (!ifbdev->fb) +if (!ifbdev->vma)return ;if (drm_fb_helper_restore_fbdev_mode_unlocked (&ifbdev->helper) ==0 )
Greg Kroah-Hartman
maintainerPATCH 193/196 drm/i915: Hold RPM wakelock while initializing OA buffer
In reply to Greg Kroah-Hartman4.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: [email protected] <[email protected]>
commit 04941829b0049d2446c7042ab9686dd057d809a6 upstream.
OA buffer initialization involves access to HW registers to set the OA base, head and tail. Ensure device is awake while setting these. With this, all oa.ops are covered under RPM and forcewake wakelock.
--- drivers/gpu/drm/i915/i915_perf.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
drivers/gpu/drm/i915/i915_perf.c +6 -6
@@ -1210,10 +1210,6 @@ static int i915_oa_stream_init(struct i9return ret; } - ret =alloc_oa_buffer (dev_priv); -if (ret) - goto err_oa_buf_alloc; -/* PRM - observability performance counters: * * OACONTROL, performance counter enable, note:
@@ -1229,6 +1225,10 @@ static int i915_oa_stream_init(struct i9intel_runtime_pm_get (dev_priv);intel_uncore_forcewake_get (dev_priv,FORCEWAKE_ALL ); + ret =alloc_oa_buffer (dev_priv); +if (ret) + goto err_oa_buf_alloc; + ret = dev_priv->perf.oa.ops.enable_metric_set (dev_priv);if (ret) goto err_enable;
@@ -1240,11 +1240,11 @@ static int i915_oa_stream_init(struct i9return 0 ; err_enable: -intel_uncore_forcewake_put (dev_priv,FORCEWAKE_ALL ); -intel_runtime_pm_put (dev_priv);free_oa_buffer (dev_priv); err_oa_buf_alloc: +intel_uncore_forcewake_put (dev_priv,FORCEWAKE_ALL ); +intel_runtime_pm_put (dev_priv);if (stream->ctx)oa_put_render_ctx_id (stream);
Greg Kroah-Hartman
maintainerPATCH 195/196 smp/hotplug: Move unparking of percpu threads to the control CPU
In reply to Greg Kroah-Hartman4.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Gleixner <[email protected]>
commit 9cd4f1a4e7a858849e889a081a99adff83e08e4c upstream.
Vikram reported the following backtrace:
BUG: scheduling while atomic: swapper/7/0/0x00000002 CPU: 7 PID: 0 Comm: swapper/7 Not tainted 4.9.32-perf+ #680 schedule schedule_hrtimeout_range_clock schedule_hrtimeout wait_task_inactive __kthread_bind_mask __kthread_bind __kthread_unpark kthread_unpark cpuhp_online_idle cpu_startup_entry secondary_start_kernel
He analyzed correctly that a parked cpu hotplug thread of an offlined CPU was still on the runqueue when the CPU came back online and tried to unpark it. This causes the thread which invoked kthread_unpark() to call wait_task_inactive() and subsequently schedule() with preemption disabled. His proposed workaround was to "make sure" that a parked thread has scheduled out when the CPU goes offline, so the situation cannot happen.
But that's still wrong because the root cause is not the fact that the percpu thread is still on the runqueue and neither that preemption is disabled, which could be simply solved by enabling preemption before calling kthread_unpark().
The real issue is that the calling thread is the idle task of the upcoming CPU, which is not supposed to call anything which might sleep. The moron, who wrote that code, missed completely that kthread_unpark() might end up in schedule().
The solution is simpler than expected. The thread which controls the hotplug operation is waiting for the CPU to call complete() on the hotplug state completion. So the idle task of the upcoming CPU can set its state to CPUHP_AP_ONLINE_IDLE and invoke complete(). This in turn wakes the control task on a different CPU, which then can safely do the unpark and kick the now unparked hotplug thread of the upcoming CPU to complete the bringup to the final target state.
Control CPU AP
bringup_cpu();
__cpu_up() ------------>
bringup_ap();
bringup_wait_for_ap()
wait_for_completion();
cpuhp_online_idle();
<------------ complete();
unpark(AP->stopper);
unpark(AP->hotplugthread);
while(1)
do_idle();
kick(AP->hotplugthread);
wait_for_completion(); hotplug_thread()
run_online_callbacks();
complete();--- kernel/cpu.c | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-)
kernel/cpu.c +19 -18
@@ -346,11 +346,25 @@ EXPORT_SYMBOL_GPL(cpu_hotplug_enable);/* Notifier wrappers for transitioning to state machine */ +static void __cpuhp_kick_ap_work (struct cpuhp_cpu_state *st); +static int bringup_wait_for_ap (unsigned int cpu) {struct cpuhp_cpu_state *st =per_cpu_ptr (&cpuhp_state, cpu); +/* Wait for the CPU to reach CPUHP_AP_ONLINE_IDLE */ wait_for_completion (&st->done); +BUG_ON (!cpu_online (cpu)); + +/* Unpark the stopper thread and the hotplug thread of the target cpu */ +stop_machine_unpark (cpu); +kthread_unpark (st->thread); + +/* Should we go further up ? */ +if (st->target >CPUHP_AP_ONLINE_IDLE ) { +__cpuhp_kick_ap_work (st); +wait_for_completion (&st->done); + }return st->result; }
@@ -371,9 +385,7 @@ static int bringup_cpu(unsigned int cpu)irq_unlock_sparse ();if (ret)return ret; - ret =bringup_wait_for_ap (cpu); -BUG_ON (!cpu_online (cpu)); -return ret; +return bringup_wait_for_ap (cpu); }/*
@@ -859,31 +871,20 @@ void notify_cpu_starting(unsigned int cp }/* -* Called from the idle task. We need to set active here, so we can kick off -* the stopper thread and unpark the smpboot threads. If the target state is -* beyond CPUHP_AP_ONLINE_IDLE we kick cpuhp thread and let it bring up the -* cpu further. +* Called from the idle task. Wake up the controlling task which brings the +* stopper and the hotplug thread of the upcoming CPU up and then delegates +* the rest of the online bringup to the hotplug thread. */ void cpuhp_online_idle (enum cpuhp_state state) {struct cpuhp_cpu_state *st =this_cpu_ptr (&cpuhp_state); -unsigned int cpu =smp_processor_id ();/* Happens for the boot cpu */ if (state !=CPUHP_AP_ONLINE_IDLE )return ; st->state =CPUHP_AP_ONLINE_IDLE ; - -/* Unpark the stopper thread and the hotplug thread of this cpu */ -stop_machine_unpark (cpu); -kthread_unpark (st->thread); - -/* Should we go further up ? */ -if (st->target >CPUHP_AP_ONLINE_IDLE ) -__cpuhp_kick_ap_work (st); -else -complete (&st->done); +complete (&st->done); }/* Requires cpu_add_remove_lock to be held */
Greg Kroah-Hartman
maintainerPATCH 196/196 smp/hotplug: Replace BUG_ON and react useful
In reply to Greg Kroah-Hartman4.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Gleixner <[email protected]>
commit dea1d0f5f1284e3defee4b8484d9fc230686cd42 upstream.
The move of the unpark functions to the control thread moved the BUG_ON() there as well. While it made some sense in the idle thread of the upcoming CPU, it's bogus to crash the control thread on the already online CPU, especially as the function has a return value and the callsite is prepared to handle an error return.
Replace it with a WARN_ON_ONCE() and return a proper error code.
--- kernel/cpu.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
kernel/cpu.c +2 -1
@@ -354,7 +354,8 @@ static int bringup_wait_for_ap(unsigned/* Wait for the CPU to reach CPUHP_AP_ONLINE_IDLE */ wait_for_completion (&st->done); -BUG_ON (!cpu_online (cpu)); +if (WARN_ON_ONCE ((!cpu_online (cpu)))) +return -ECANCELED ;/* Unpark the stopper thread and the hotplug thread of the target cpu */ stop_machine_unpark (cpu);
Quoted 8 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 4.12.4 release. There are 196 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu Jul 27 19:20:09 UTC 2017. Anything received after that time might be too late.
Build results:
total: 145 pass: 145 fail: 0 Qemu test results: total: 122 pass: 122 fail: 0
Details are available at http://kerneltests.org/builders.
Guenter
Greg Kroah-Hartman
maintainerQuoted 10 lines · Guenter Roeck
Quoted 8 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 4.12.4 release. There are 196 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu Jul 27 19:20:09 UTC 2017. Anything received after that time might be too late.
Quoted 6 lines
Build results:
total: 145 pass: 145 fail: 0 Qemu test results: total: 122 pass: 122 fail: 0Details are available at http://kerneltests.org/builders.
Thanks for testing all of these and letting me know.
greg k-h
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 4.12.4 release. There are 196 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu Jul 27 19:20:09 UTC 2017. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 9 lines
kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.12.4-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-4.12.y
and the diffstat can be found below.thanks,
greg k-h
Compiled and booted on my test system. No dmesg regressions.
thanks,
-- Shuah
Greg Kroah-Hartman
maintainerQuoted 15 lines · Shuah Khan
Quoted 14 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 4.12.4 release. There are 196 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu Jul 27 19:20:09 UTC 2017. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.12.4-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-4.12.y
and the diffstat can be found below.
Quoted 6 lines
Quoted 4 lines
thanks,
greg k-h
Compiled and booted on my test system. No dmesg regressions.
Thanks for testing all of these and letting me know.
greg k-h