Whamcloud - gitweb
LU-12495 obdclass: generate random u64 max correctly 94/35394/5
authorLai Siyao <lai.siyao@whamcloud.com>
Fri, 28 Jun 2019 17:36:27 +0000 (01:36 +0800)
committerOleg Drokin <green@whamcloud.com>
Sun, 7 Jul 2019 15:16:05 +0000 (15:16 +0000)
Generate random u64 max number correctly, and make it an obdclass
function lu_prandom_u64_max().

Fixes: 7a707d4828 (libcfs: replace cfs_rand() with prandom_u32_max())

Signed-off-by: Lai Siyao <lai.siyao@whamcloud.com>
Change-Id: I2b94a42b42539be319f358d7af2a82dc8b26117c
Reviewed-on: https://review.whamcloud.com/35394
Tested-by: jenkins <devops@whamcloud.com>
Reviewed-by: James Simmons <uja.ornl@yahoo.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/include/lu_object.h
lustre/lmv/lmv_qos.c
lustre/lod/lod_qos.c
lustre/obdclass/lu_qos.c

index 86ed326..13720c1 100644 (file)
@@ -1470,6 +1470,7 @@ struct lu_qos {
 
 int lqos_add_tgt(struct lu_qos *qos, struct lu_tgt_desc *ltd);
 int lqos_del_tgt(struct lu_qos *qos, struct lu_tgt_desc *ltd);
+u64 lu_prandom_u64_max(u64 ep_ro);
 
 /** @} lu */
 #endif /* __LUSTRE_LU_OBJECT_H */
index 77e95d3..1708c00 100644 (file)
@@ -372,30 +372,7 @@ struct lu_tgt_desc *lmv_locate_tgt_qos(struct lmv_obd *lmv, __u32 *mdt)
                total_weight += tgt->ltd_qos.ltq_weight;
        }
 
-       if (total_weight) {
-#if BITS_PER_LONG == 32
-               rand = prandom_u32_max((u32)total_weight);
-               /*
-                * If total_weight > 32-bit, first generate the high
-                * 32 bits of the random number, then add in the low
-                * 32 bits (truncated to the upper limit, if needed)
-                */
-               if (total_weight > 0xffffffffULL)
-                       rand = prandom_u32_max((u32)(total_weight >> 32)) << 32;
-               else
-                       rand = 0;
-
-               if (rand == (total_weight & 0xffffffff00000000ULL))
-                       rand |= prandom_u32_max((u32)total_weight);
-               else
-                       rand |= prandom_u32();
-
-#else
-               rand = prandom_u32() | prandom_u32_max((u32)total_weight);
-#endif
-       } else {
-               rand = 0;
-       }
+       rand = lu_prandom_u64_max(total_weight);
 
        for (i = 0; i < lmv->desc.ld_tgt_count; i++) {
                tgt = lmv->tgts[i];
index 1e2645b..fbc35cd 100644 (file)
@@ -1548,29 +1548,7 @@ static int lod_alloc_qos(const struct lu_env *env, struct lod_object *lo,
                cur_weight = 0;
                rc = -ENOSPC;
 
-               if (total_weight) {
-#if BITS_PER_LONG == 32
-                       rand = prandom_u32_max((u32)total_weight);
-                       /* If total_weight > 32-bit, first generate the high
-                        * 32 bits of the random number, then add in the low
-                        * 32 bits (truncated to the upper limit, if needed)
-                        */
-                       if (total_weight > 0xffffffffULL)
-                               rand = prandom_u32_max((u32)(total_weight >> 32)) << 32;
-                       else
-                               rand = 0;
-
-                       if (rand == (total_weight & 0xffffffff00000000ULL))
-                               rand |= prandom_u32_max((u32)total_weight);
-                       else
-                               rand |= prandom_u32();
-
-#else
-                       rand = prandom_u32() | prandom_u32_max((u32)total_weight);
-#endif
-               } else {
-                       rand = 0;
-               }
+               rand = lu_prandom_u64_max(total_weight);
 
                /* On average, this will hit larger-weighted OSTs more often.
                 * 0-weight OSTs will always get used last (only when rand=0) */
index 0e04bdd..ade9c1f 100644 (file)
@@ -34,6 +34,7 @@
 
 #include <linux/module.h>
 #include <linux/list.h>
+#include <linux/random.h>
 #include <libcfs/libcfs.h>
 #include <libcfs/libcfs_hash.h> /* hash_long() */
 #include <libcfs/linux/linux-mem.h>
@@ -166,3 +167,38 @@ out:
        RETURN(rc);
 }
 EXPORT_SYMBOL(lqos_del_tgt);
+
+/**
+ * lu_prandom_u64_max - returns a pseudo-random u64 number in interval
+ * [0, ep_ro)
+ *
+ * \param[in] ep_ro    right open interval endpoint
+ *
+ * \retval a pseudo-random 64-bit number that is in interval [0, ep_ro).
+ */
+u64 lu_prandom_u64_max(u64 ep_ro)
+{
+       u64 rand = 0;
+
+       if (ep_ro) {
+#if BITS_PER_LONG == 32
+               /*
+                * If ep_ro > 32-bit, first generate the high
+                * 32 bits of the random number, then add in the low
+                * 32 bits (truncated to the upper limit, if needed)
+                */
+               if (ep_ro > 0xffffffffULL)
+                       rand = prandom_u32_max((u32)(ep_ro >> 32)) << 32;
+
+               if (rand == (ep_ro & 0xffffffff00000000ULL))
+                       rand |= prandom_u32_max((u32)ep_ro);
+               else
+                       rand |= prandom_u32();
+#else
+               rand = ((u64)prandom_u32() << 32 | prandom_u32()) % ep_ro;
+#endif
+       }
+
+       return rand;
+}
+EXPORT_SYMBOL(lu_prandom_u64_max);