From 7a707d4828807b45aeca368e707c243ba68fa51f Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Wed, 19 Jun 2019 22:57:13 -0400 Subject: [PATCH] LU-9859 libcfs: replace cfs_rand() with prandom_u32_max() All occurrences of cfs_rand() % X are replaced with prandom_u32_max(X) cfs_rand() is a simple Linear Congruential PRNG. prandom_u32_max() is at least as random, is seeded with more randomness, and uses cpu-local state to avoid cross-cpu issues. This is the first step is discarding the libcfs prng with the standard linux prng. Linux-commit: bcfa98a50763a0f781a8441d1994ae1456816219 Change-Id: I63679c269b72f4c4860cb3a47225178edf2d7892 Signed-off-by: NeilBrown Signed-off-by: Greg Kroah-Hartman Reviewed-on: https://review.whamcloud.com/35272 Reviewed-by: Andreas Dilger Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Oleg Drokin --- contrib/scripts/spelling.txt | 2 ++ libcfs/libcfs/fail.c | 3 ++- lnet/lnet/net_fault.c | 31 +++++++++++++++---------------- lnet/lnet/router.c | 2 +- lustre/lmv/lmv_qos.c | 13 +++++++------ lustre/lod/lod_qos.c | 21 +++++++++++---------- lustre/mgc/mgc_request.c | 5 +++-- lustre/obdclass/llog_test.c | 3 ++- lustre/ptlrpc/nrs_delay.c | 10 ++++++---- 9 files changed, 49 insertions(+), 41 deletions(-) diff --git a/contrib/scripts/spelling.txt b/contrib/scripts/spelling.txt index 14c07ba..c964883 100644 --- a/contrib/scripts/spelling.txt +++ b/contrib/scripts/spelling.txt @@ -84,6 +84,8 @@ CFS_PAGE_MASK||PAGE_MASK CFS_PAGE_SIZE||PAGE_SIZE cfs_proc_dir_entry_t||struct proc_dir_entry cfs_rcu_head_t||struct rcu_head +cfs_rand||prandom_u32 +cfs_srand||add_device_randomness cfs_trimwhite||strim cfs_time_add_64||ktime_add cfs_time_after||time_after diff --git a/libcfs/libcfs/fail.c b/libcfs/libcfs/fail.c index 13d31ab..9e564e9 100644 --- a/libcfs/libcfs/fail.c +++ b/libcfs/libcfs/fail.c @@ -29,6 +29,7 @@ * Lustre is a trademark of Oracle Corporation, Inc. */ +#include #include unsigned long cfs_fail_loc = 0; @@ -57,7 +58,7 @@ int __cfs_fail_check_set(__u32 id, __u32 value, int set) /* Fail 1/cfs_fail_val times */ if (cfs_fail_loc & CFS_FAIL_RAND) { - if (cfs_fail_val < 2 || cfs_rand() % cfs_fail_val > 0) + if (cfs_fail_val < 2 || prandom_u32_max(cfs_fail_val) > 0) return 0; } diff --git a/lnet/lnet/net_fault.c b/lnet/lnet/net_fault.c index 7fdd8df..4f1bc30 100644 --- a/lnet/lnet/net_fault.c +++ b/lnet/lnet/net_fault.c @@ -36,6 +36,7 @@ #define DEBUG_SUBSYSTEM S_LNET +#include #include #include @@ -174,9 +175,9 @@ lnet_drop_rule_add(struct lnet_fault_attr *attr) if (attr->u.drop.da_interval != 0) { rule->dr_time_base = ktime_get_seconds() + attr->u.drop.da_interval; rule->dr_drop_time = ktime_get_seconds() + - cfs_rand() % attr->u.drop.da_interval; + prandom_u32_max(attr->u.drop.da_interval); } else { - rule->dr_drop_at = cfs_rand() % attr->u.drop.da_rate; + rule->dr_drop_at = prandom_u32_max(attr->u.drop.da_rate); } lnet_net_lock(LNET_LOCK_EX); @@ -283,10 +284,10 @@ lnet_drop_rule_reset(void) memset(&rule->dr_stat, 0, sizeof(rule->dr_stat)); if (attr->u.drop.da_rate != 0) { - rule->dr_drop_at = cfs_rand() % attr->u.drop.da_rate; + rule->dr_drop_at = prandom_u32_max(attr->u.drop.da_rate); } else { rule->dr_drop_time = ktime_get_seconds() + - cfs_rand() % attr->u.drop.da_interval; + prandom_u32_max(attr->u.drop.da_interval); rule->dr_time_base = ktime_get_seconds() + attr->u.drop.da_interval; } spin_unlock(&rule->dr_lock); @@ -299,15 +300,13 @@ lnet_drop_rule_reset(void) static void lnet_fault_match_health(enum lnet_msg_hstatus *hstatus, __u32 mask) { - unsigned int random; int choice; int delta; int best_delta; int i; /* assign a random failure */ - random = cfs_rand(); - choice = random % (LNET_MSG_STATUS_END - LNET_MSG_STATUS_OK); + choice = prandom_u32_max(LNET_MSG_STATUS_END - LNET_MSG_STATUS_OK); if (choice == 0) choice++; @@ -373,7 +372,7 @@ drop_rule_match(struct lnet_drop_rule *rule, lnet_nid_t src, /* match this rule, check drop rate now */ spin_lock(&rule->dr_lock); if (attr->u.drop.da_random) { - int value = cfs_rand() % attr->u.drop.da_interval; + int value = prandom_u32_max(attr->u.drop.da_interval); if (value >= (attr->u.drop.da_interval / 2)) drop = true; else @@ -388,7 +387,7 @@ drop_rule_match(struct lnet_drop_rule *rule, lnet_nid_t src, rule->dr_time_base = now; rule->dr_drop_time = rule->dr_time_base + - cfs_rand() % attr->u.drop.da_interval; + prandom_u32_max(attr->u.drop.da_interval); rule->dr_time_base += attr->u.drop.da_interval; CDEBUG(D_NET, "Drop Rule %s->%s: next drop : %lld\n", @@ -404,7 +403,7 @@ drop_rule_match(struct lnet_drop_rule *rule, lnet_nid_t src, count = rule->dr_stat.fs_count; if (do_div(count, attr->u.drop.da_rate) == 0) { rule->dr_drop_at = rule->dr_stat.fs_count + - cfs_rand() % attr->u.drop.da_rate; + prandom_u32_max(attr->u.drop.da_rate); CDEBUG(D_NET, "Drop Rule %s->%s: next drop: %lu\n", libcfs_nid2str(attr->fa_src), libcfs_nid2str(attr->fa_dst), rule->dr_drop_at); @@ -557,7 +556,7 @@ delay_rule_match(struct lnet_delay_rule *rule, lnet_nid_t src, rule->dl_time_base = now; rule->dl_delay_time = rule->dl_time_base + - cfs_rand() % attr->u.delay.la_interval; + prandom_u32_max(attr->u.delay.la_interval); rule->dl_time_base += attr->u.delay.la_interval; CDEBUG(D_NET, "Delay Rule %s->%s: next delay : %lld\n", @@ -574,7 +573,7 @@ delay_rule_match(struct lnet_delay_rule *rule, lnet_nid_t src, count = rule->dl_stat.fs_count; if (do_div(count, attr->u.delay.la_rate) == 0) { rule->dl_delay_at = rule->dl_stat.fs_count + - cfs_rand() % attr->u.delay.la_rate; + prandom_u32_max(attr->u.delay.la_rate); CDEBUG(D_NET, "Delay Rule %s->%s: next delay: %lu\n", libcfs_nid2str(attr->fa_src), libcfs_nid2str(attr->fa_dst), rule->dl_delay_at); @@ -849,9 +848,9 @@ lnet_delay_rule_add(struct lnet_fault_attr *attr) rule->dl_time_base = ktime_get_seconds() + attr->u.delay.la_interval; rule->dl_delay_time = ktime_get_seconds() + - cfs_rand() % attr->u.delay.la_interval; + prandom_u32_max(attr->u.delay.la_interval); } else { - rule->dl_delay_at = cfs_rand() % attr->u.delay.la_rate; + rule->dl_delay_at = prandom_u32_max(attr->u.delay.la_rate); } rule->dl_msg_send = -1; @@ -998,10 +997,10 @@ lnet_delay_rule_reset(void) memset(&rule->dl_stat, 0, sizeof(rule->dl_stat)); if (attr->u.delay.la_rate != 0) { - rule->dl_delay_at = cfs_rand() % attr->u.delay.la_rate; + rule->dl_delay_at = prandom_u32_max(attr->u.delay.la_rate); } else { rule->dl_delay_time = ktime_get_seconds() + - cfs_rand() % attr->u.delay.la_interval; + prandom_u32_max(attr->u.delay.la_interval); rule->dl_time_base = ktime_get_seconds() + attr->u.delay.la_interval; } diff --git a/lnet/lnet/router.c b/lnet/lnet/router.c index ec92e1a..599a8a1 100644 --- a/lnet/lnet/router.c +++ b/lnet/lnet/router.c @@ -404,7 +404,7 @@ lnet_add_route_to_rnet(struct lnet_remotenet *rnet, struct lnet_route *route) * different nodes are using the same list of routers, they end up * preferring different routers. */ - offset = cfs_rand() % (len + 1); + offset = prandom_u32_max(len + 1); list_for_each(e, &rnet->lrn_routes) { if (offset == 0) break; diff --git a/lustre/lmv/lmv_qos.c b/lustre/lmv/lmv_qos.c index 685cc01..77e95d3 100644 --- a/lustre/lmv/lmv_qos.c +++ b/lustre/lmv/lmv_qos.c @@ -33,6 +33,8 @@ #define DEBUG_SUBSYSTEM S_LMV #include +#include + #include #include #include @@ -372,25 +374,24 @@ struct lu_tgt_desc *lmv_locate_tgt_qos(struct lmv_obd *lmv, __u32 *mdt) if (total_weight) { #if BITS_PER_LONG == 32 - rand = cfs_rand() % (unsigned int)total_weight; + 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 = (__u64)(cfs_rand() % - (unsigned int)(total_weight >> 32)) << 32; + rand = prandom_u32_max((u32)(total_weight >> 32)) << 32; else rand = 0; if (rand == (total_weight & 0xffffffff00000000ULL)) - rand |= cfs_rand() % (unsigned int)total_weight; + rand |= prandom_u32_max((u32)total_weight); else - rand |= cfs_rand(); + rand |= prandom_u32(); #else - rand = ((__u64)cfs_rand() << 32 | cfs_rand()) % total_weight; + rand = prandom_u32() | prandom_u32_max((u32)total_weight); #endif } else { rand = 0; diff --git a/lustre/lod/lod_qos.c b/lustre/lod/lod_qos.c index aca8fc7..1e2645b 100644 --- a/lustre/lod/lod_qos.c +++ b/lustre/lod/lod_qos.c @@ -38,6 +38,8 @@ #define DEBUG_SUBSYSTEM S_LOV #include +#include + #include #include #include @@ -979,7 +981,7 @@ static int lod_alloc_rr(const struct lu_env *env, struct lod_object *lo, down_read(&m->lod_qos.lq_rw_sem); spin_lock(&lqr->lqr_alloc); if (--lqr->lqr_start_count <= 0) { - lqr->lqr_start_idx = cfs_rand() % osts->op_count; + lqr->lqr_start_idx = prandom_u32_max(osts->op_count); lqr->lqr_start_count = (LOV_CREATE_RESEED_MIN / max(osts->op_count, 1U) + LOV_CREATE_RESEED_MULT) * max(osts->op_count, 1U); @@ -1541,31 +1543,30 @@ static int lod_alloc_qos(const struct lu_env *env, struct lod_object *lo, /* Find enough OSTs with weighted random allocation. */ nfound = 0; while (nfound < stripe_count) { - __u64 rand, cur_weight; + u64 rand, cur_weight; cur_weight = 0; rc = -ENOSPC; if (total_weight) { #if BITS_PER_LONG == 32 - rand = cfs_rand() % (unsigned)total_weight; + 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) */ + * 32 bits (truncated to the upper limit, if needed) + */ if (total_weight > 0xffffffffULL) - rand = (__u64)(cfs_rand() % - (unsigned)(total_weight >> 32)) << 32; + rand = prandom_u32_max((u32)(total_weight >> 32)) << 32; else rand = 0; if (rand == (total_weight & 0xffffffff00000000ULL)) - rand |= cfs_rand() % (unsigned)total_weight; + rand |= prandom_u32_max((u32)total_weight); else - rand |= cfs_rand(); + rand |= prandom_u32(); #else - rand = ((__u64)cfs_rand() << 32 | cfs_rand()) % - total_weight; + rand = prandom_u32() | prandom_u32_max((u32)total_weight); #endif } else { rand = 0; diff --git a/lustre/mgc/mgc_request.c b/lustre/mgc/mgc_request.c index 91910a9..d646c7f 100644 --- a/lustre/mgc/mgc_request.c +++ b/lustre/mgc/mgc_request.c @@ -39,6 +39,7 @@ #include #include +#include #include #include @@ -611,7 +612,7 @@ static void do_requeue(struct config_llog_data *cld) * in order to not flood the MGS. */ #define MGC_TIMEOUT_MIN_SECONDS 5 -#define MGC_TIMEOUT_RAND_CENTISEC 0x1ff /* ~500 */ +#define MGC_TIMEOUT_RAND_CENTISEC 500 static int mgc_requeue_thread(void *data) { @@ -627,7 +628,7 @@ static int mgc_requeue_thread(void *data) while (!(rq_state & RQ_STOP)) { struct l_wait_info lwi; struct config_llog_data *cld, *cld_prev; - int rand = cfs_rand() & MGC_TIMEOUT_RAND_CENTISEC; + int rand = prandom_u32_max(MGC_TIMEOUT_RAND_CENTISEC); int to; /* Any new or requeued lostlocks will change the state */ diff --git a/lustre/obdclass/llog_test.c b/lustre/obdclass/llog_test.c index 856e8d0..9f15a9e 100644 --- a/lustre/obdclass/llog_test.c +++ b/lustre/obdclass/llog_test.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include @@ -2248,7 +2249,7 @@ static int llog_test_setup(struct obd_device *obd, struct lustre_cfg *lcfg) ctxt->loc_dir = o; llog_ctxt_put(ctxt); - llog_test_rand = cfs_rand(); + llog_test_rand = prandom_u32(); rc = llog_run_tests(&env, tgt); if (rc) diff --git a/lustre/ptlrpc/nrs_delay.c b/lustre/ptlrpc/nrs_delay.c index fec9c2f..301b08c 100644 --- a/lustre/ptlrpc/nrs_delay.c +++ b/lustre/ptlrpc/nrs_delay.c @@ -39,6 +39,9 @@ */ #define DEBUG_SUBSYSTEM S_RPC + +#include + #include #include #include "ptlrpc_internal.h" @@ -252,12 +255,11 @@ static int nrs_delay_req_add(struct ptlrpc_nrs_policy *policy, if (delay_data->delay_pct == 0 || /* Not delaying anything */ (delay_data->delay_pct != 100 && - delay_data->delay_pct < cfs_rand() % 100)) + delay_data->delay_pct < prandom_u32_max(100))) return 1; - nrq->nr_u.delay.req_start_time = ktime_get_real_seconds() + cfs_rand() % - (delay_data->max_delay - - delay_data->min_delay + 1) + + nrq->nr_u.delay.req_start_time = ktime_get_real_seconds() + + prandom_u32_max(delay_data->max_delay - delay_data->min_delay + 1) + delay_data->min_delay; return cfs_binheap_insert(delay_data->delay_binheap, &nrq->nr_node); -- 1.8.3.1