Patch "dm round robin: revert "use percpu 'repeat_count' and 'current_path'"" has been added to the 4.9-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
dm round robin: revert "use percpu 'repeat_count' and 'current_path'"
to the 4.9-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
dm-round-robin-revert-use-percpu-repeat_count-and-current_path.patch
and it can be found in the queue-4.9 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
37a098e9d10db6e2efc05fe61e3a6ff2e9802c53Mon Sep 17 00:00:00 2001
From: Mike Snitzer <[email protected]>
Date: Thu, 16 Feb 2017 23:57:17 -0500
Subject: dm round robin: revert "use percpu 'repeat_count' and 'current_path'"
From: Mike Snitzer <[email protected]>
commit 37a098e9d10db6e2efc05fe61e3a6ff2e9802c53 upstream.
The sloppy nature of lockless access to percpu pointers (s->current_path) in rr_select_path(), from multiple threads, is causing some paths to used more than others -- which results in less IO performance being observed.
Revert these upstream commits to restore truly symmetric round-robin IO submission in DM multipath:
b0b477c dm round robin: use percpu 'repeat_count' and 'current_path' 802934b dm round robin: do not use this_cpu_ptr() without having preemption disabled
There is no benefit to all this complexity if repeat_count = 1 (which is the recommended default).
--- drivers/md/dm-round-robin.c | 67 +++++++++----------------------------------- 1 file changed, 14 insertions(+), 53 deletions(-)
drivers/md/dm-round-robin.c +14 -53
@@ -17,8 +17,8 @@#include <linux/module.h> #define DM_MSG_PREFIX "multipath round-robin" -#define RR_MIN_IO 1000 -#define RR_VERSION "1.1.0" +#define RR_MIN_IO 1 +#define RR_VERSION "1.2.0"/*----------------------------------------------------------------- * Path-handling code, paths are held in lists
@@ -47,44 +47,19 @@ struct selector {struct list_head valid_paths;struct list_head invalid_paths;spinlock_t lock; -struct dm_path *__percpu *current_path; -struct percpu_counter repeat_count; }; -static void set_percpu_current_path (struct selector *s,struct dm_path *path) -{ -int cpu; - -for_each_possible_cpu (cpu) - *per_cpu_ptr (s->current_path, cpu) = path; -} -static struct selector *alloc_selector (void ) {struct selector *s =kmalloc (sizeof (*s),GFP_KERNEL ); -if (!s) -return NULL ; - -INIT_LIST_HEAD (&s->valid_paths); -INIT_LIST_HEAD (&s->invalid_paths); -spin_lock_init (&s->lock); - - s->current_path = alloc_percpu(struct dm_path *); -if (!s->current_path) - goto out_current_path; -set_percpu_current_path (s,NULL ); - -if (percpu_counter_init (&s->repeat_count,0 ,GFP_KERNEL )) - goto out_repeat_count; +if (s) { +INIT_LIST_HEAD (&s->valid_paths); +INIT_LIST_HEAD (&s->invalid_paths); +spin_lock_init (&s->lock); + }return s; - -out_repeat_count: -free_percpu (s->current_path); -out_current_path: -kfree (s); -return NULL ;; }static int rr_create (struct path_selector *ps,unsigned argc,char **argv)
@@ -105,8 +80,6 @@ static void rr_destroy(struct path_selecfree_paths (&s->valid_paths);free_paths (&s->invalid_paths); -free_percpu (s->current_path); -percpu_counter_destroy (&s->repeat_count);kfree (s); ps->context =NULL ; }
@@ -157,6 +130,11 @@ static int rr_add_path(struct path_selecreturn -EINVAL ; } +if (repeat_count >1 ) { +DMWARN_LIMIT ("repeat_count > 1 is deprecated, using 1 instead" ); + repeat_count =1 ; + } +/* allocate the path */ pi =kmalloc (sizeof (*pi),GFP_KERNEL );if (!pi) {
@@ -183,9 +161,6 @@ static void rr_fail_path(struct path_selstruct path_info *pi = p->pscontext;spin_lock_irqsave (&s->lock, flags); -if (p == *this_cpu_ptr (s->current_path)) -set_percpu_current_path (s,NULL ); -list_move (&pi->list, &s->invalid_paths);spin_unlock_irqrestore (&s->lock, flags); }
@@ -208,29 +183,15 @@ static struct dm_path *rr_select_path(stunsigned long flags;struct selector *s = ps->context;struct path_info *pi =NULL ; -struct dm_path *current_path =NULL ; -local_irq_save (flags); - current_path = *this_cpu_ptr (s->current_path); -if (current_path) { -percpu_counter_dec (&s->repeat_count); -if (percpu_counter_read_positive (&s->repeat_count) >0 ) { -local_irq_restore (flags); -return current_path; - } - } - -spin_lock (&s->lock); +spin_lock_irqsave (&s->lock, flags);if (!list_empty (&s->valid_paths)) { pi = list_entry(s->valid_paths.next, struct path_info, list);list_move_tail (&pi->list, &s->valid_paths); -percpu_counter_set (&s->repeat_count, pi->repeat_count); -set_percpu_current_path (s, pi->path); - current_path = pi->path; }spin_unlock_irqrestore (&s->lock, flags); -return current_path; +return pi ? pi->path :NULL ; }static struct path_selector_type rr_ps = {
Patches currently in stable-queue which might be from [email protected] are
queue-4.9/dm-stats-fix-a-leaked-s-histogram_boundaries-array.patch queue-4.9/dm-round-robin-revert-use-percpu-repeat_count-and-current_path.patch queue-4.9/dm-raid-fix-data-corruption-on-reshape-request.patch queue-4.9/dm-cache-fix-corruption-seen-when-using-cache-2tb.patch