[dm-devel] [PATCH 2/2] multipath-tools/libmultipath: Add args min_avg_latency for path_latency.

Yang Feng philip.yang at huawei.com
Thu Jul 13 07:51:28 UTC 2017


  Add args min_avg_latency of logarithmic scale, for prioritizers/path_latency.c.
Min average latency is not constant 1us, and is set by user. Certainly, max average
latency value is still 100s. It make support better for more scenes, because it can
deal better with the normal standard deviation of path latency. For example, when the
standard deviation value is 200us and the average latency of the normal paths is 1ms,
args base_num can be set to 5 and args min_avg_latency can be set to 2ms, so the paths
will be grouped in priority groups with path latency <=2ms, (2ms, 10ms], (10ms, 50ms],
etc.

Signed-off-by: Yang Feng <philip.yang at huawei.com>
---
 libmultipath/prioritizers/path_latency.c | 61 ++++++++++++++++++++++----------
 multipath/multipath.conf.5               | 14 +++++---
 2 files changed, 52 insertions(+), 23 deletions(-)

diff --git a/libmultipath/prioritizers/path_latency.c b/libmultipath/prioritizers/path_latency.c
index 21209ff..c8fe318 100644
--- a/libmultipath/prioritizers/path_latency.c
+++ b/libmultipath/prioritizers/path_latency.c
@@ -76,7 +76,7 @@ static int do_readsector0(struct path *pp, unsigned int timeout)
     return 1;
 }
 
-int check_args_valid(int io_num, int base_num)
+int check_args_valid(int io_num, int base_num, int min_avg_latency)
 {
     if ((io_num < MIN_IO_NUM) || (io_num > MAX_IO_NUM))
     {
@@ -90,24 +90,33 @@ int check_args_valid(int io_num, int base_num)
         return 0;
     }
 
+    if ((min_avg_latency < MIN_AVG_LATENCY) || (min_avg_latency > MAX_AVG_LATENCY))
+    {
+        pp_pl_log(0, "args min_avg_latency is outside the valid range");
+        return 0;
+    }
+
     return 1;
 }
 
-/* In multipath.conf, args form: io_num|base_num. For example,
-*  args is "20|10", this function can get io_num value 20, and
-   base_num value 10.
+/* In multipath.conf, args form: io_num|base_num|min_avg_latency.
+*  For example, args is "20|10|1", this function can get io_num
+*  value 20, base_num value 10, min_avg_latency value 1 (us).
 */
-static int get_ionum_and_basenum(char *args,
-                                 int *ionum,
-                                 int *basenum)
+static int get_prio_args(char *args,
+                    int *ionum,
+                    int *basenum,
+                    int *minavglatency)
 {
     char source[MAX_CHAR_SIZE];
     char vertica = '|';
-    char *endstrbefore = NULL;
-    char *endstrafter = NULL;
+    char *endstr1 = NULL;
+    char *endstr2 = NULL;
+    char *endstr3 = NULL;
     unsigned int size = strlen(args);
 
-    if ((args == NULL) || (ionum == NULL) || (basenum == NULL))
+    if ((args == NULL) || (ionum == NULL)
+        || (basenum == NULL) || (minavglatency == NULL))
     {
         pp_pl_log(0, "args string is NULL");
         return 0;
@@ -127,21 +136,34 @@ static int get_ionum_and_basenum(char *args,
         return 0;
     }
 
-    *ionum = (int)strtoul(source, &endstrbefore, 10);
-    if (endstrbefore[0] != vertica)
+    *ionum = (int)strtoul(source, &endstr1, 10);
+    if (endstr1[0] != vertica)
+    {
+        pp_pl_log(0, "invalid prio_args format: %s", source);
+        return 0;
+    }
+
+    if (!isdigit(endstr1[1]))
+    {
+        pp_pl_log(0, "invalid prio_args format: %s", source);
+        return 0;
+    }
+
+    *basenum = (long long)strtol(&endstr1[1], &endstr2, 10);
+    if (endstr2[0] != vertica)
     {
         pp_pl_log(0, "invalid prio_args format: %s", source);
         return 0;
     }
 
-    if (!isdigit(endstrbefore[1]))
+    if (!isdigit(endstr2[1]))
     {
         pp_pl_log(0, "invalid prio_args format: %s", source);
         return 0;
     }
 
-    *basenum = (long long)strtol(&endstrbefore[1], &endstrafter, 10);
-    if (check_args_valid(*ionum, *basenum) == 0)
+    *minavglatency = (long long)strtol(&endstr2[1], &endstr3, 10);
+    if (check_args_valid(*ionum, *basenum, *minavglatency) == 0)
     {
         return 0;
     }
@@ -204,6 +226,7 @@ int getprio (struct path *pp, char *args, unsigned int timeout)
     int index = 0;
     int io_num;
     int base_num;
+    int min_avg_latency;
     long long avglatency;
     long long latency_interval;
     long long standard_deviation;
@@ -214,7 +237,7 @@ int getprio (struct path *pp, char *args, unsigned int timeout)
     if (pp->fd < 0)
         return -1;
 
-    if (get_ionum_and_basenum(args, &io_num, &base_num) == 0)
+    if (get_prio_args(args, &io_num, &base_num, &min_avg_latency) == 0)
     {
         pp_pl_log(0, "%s: get path_latency args fail", pp->dev);
         return DEFAULT_PRIORITY;
@@ -255,13 +278,13 @@ int getprio (struct path *pp, char *args, unsigned int timeout)
     set can change latency_interval value corresponding to avglatency and is not constant.
     Warn the user if latency_interval is smaller than (2 * standard_deviation), or equal */
     standard_deviation = calc_standard_deviation(path_latency, index, avglatency);
-    latency_interval = calc_latency_interval(avglatency, MAX_AVG_LATENCY, MIN_AVG_LATENCY, base_num);
-    if ((latency_interval!= 0)
+    latency_interval = calc_latency_interval(avglatency, MAX_AVG_LATENCY, min_avg_latency, base_num);
+    if ((latency_interval != 0)
         && (latency_interval <= (2 * standard_deviation)))
         pp_pl_log(3, "%s: latency interval (%lld) according to average latency (%lld us) is smaller than "
             "2 * standard deviation (%lld us), or equal, args base_num (%d) needs to be set bigger value",
             pp->dev, latency_interval, avglatency, standard_deviation, base_num);
 
-    rc = calcPrio(avglatency, MAX_AVG_LATENCY, MIN_AVG_LATENCY, base_num);
+    rc = calcPrio(avglatency, MAX_AVG_LATENCY, min_avg_latency, base_num);
     return rc;
 }
diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5
index 915cc50..e3fb461 100644
--- a/multipath/multipath.conf.5
+++ b/multipath/multipath.conf.5
@@ -341,7 +341,7 @@ these values can be looked up through sysfs or by running \fImultipathd show pat
 .TP 12
 .I path_latency
 Needs a value of the form
-\fI"<io_num>|<base_num>"\fR
+\fI"<io_num>|<base_num>|<min_avg_latency>"\fR
 .RS
 .TP 8
 .I io_num
@@ -350,9 +350,15 @@ Valid Values: Integer, [2, 200].
 .TP
 .I base_num
 The base number value of logarithmic scale, used to partition different priority ranks. Valid Values: Integer,
-[2, 10]. And Max average latency value is 100s, min average latency value is 1us.
-For example: If base_num=10, the paths will be grouped in priority groups with path latency <=1us, (1us, 10us],
-(10us, 100us], (100us, 1ms], (1ms, 10ms], (10ms, 100ms], (100ms, 1s], (1s, 10s], (10s, 100s], >100s.
+[2, 10]. And Max average latency value is constant 100s.
+For example: If base_num=10 and min_avg_latency=1, the paths will be grouped in priority groups with path latency <=1us,
+(1us, 10us], (10us, 100us], (100us, 1ms], (1ms, 10ms], (10ms, 100ms], (100ms, 1s], (1s, 10s], (10s, 100s], >100s.
+.TP
+.I min_avg_latency
+The min average latency value of logarithmic scale, used to partition different priority ranks. Valid Values:
+Integer, [1, 10000000] (us). And  Max average latency value is constant 100s.
+For example: If base_num=10 and min_avg_latency=1000, the paths will be grouped in priority groups with path latency <=1ms,
+(1ms, 10ms], (10ms, 100ms], (100ms, 1s], (1s, 10s], (10s, 100s], >100s.
 .RE
 .TP 12
 .I alua
-- 
2.6.4.windows.1





More information about the dm-devel mailing list