* [PATCH] ext4: add ability to control the pseudo-random seed used by ext4
@ 2016-07-29 16:00 Theodore Ts'o
2016-07-29 18:07 ` kbuild test robot
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Theodore Ts'o @ 2016-07-29 16:00 UTC (permalink / raw)
To: Ext4 Developers List; +Cc: agayev, Theodore Ts'o
Ext4 uses a pseudo-random generator in a few places: to spread out
directories when htree is not enabled; to randomize thethe wait times
for MMP backoff and lazy inode table initialization. For benchmarking
purposes, it's useful to control the psueorandom number seed, expose
this via /sys/fs/ext4/<dev>/prandom_seed.
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
---
fs/ext4/ext4.h | 4 ++++
fs/ext4/ialloc.c | 6 ++++--
fs/ext4/mmp.c | 6 +++---
fs/ext4/super.c | 3 ++-
fs/ext4/sysfs.c | 20 ++++++++++++++++++++
include/linux/random.h | 1 +
lib/random32.c | 10 +++++-----
7 files changed, 39 insertions(+), 11 deletions(-)
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index ea31931..3dbb03a 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -35,6 +35,7 @@
#include <linux/fscrypto.h>
#include <linux/falloc.h>
#include <linux/percpu-rwsem.h>
+#include <linux/random.h>
#ifdef __KERNEL__
#include <linux/compat.h>
#endif
@@ -1491,6 +1492,9 @@ struct ext4_sb_info {
/* Precomputed FS UUID checksum for seeding other checksums */
__u32 s_csum_seed;
+ /* RND state for the file system */
+ struct rnd_state s_rnd_state;
+
/* Reclaim extents from extent status tree */
struct shrinker s_es_shrinker;
struct list_head s_es_list; /* List of inodes with reclaimable extents */
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
index 35f3518..09a1458 100644
--- a/fs/ext4/ialloc.c
+++ b/fs/ext4/ialloc.c
@@ -485,8 +485,10 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent,
hinfo.seed = sbi->s_hash_seed;
ext4fs_dirhash(qstr->name, qstr->len, &hinfo);
grp = hinfo.hash;
- } else
- grp = prandom_u32();
+ } else {
+ grp = prandom_u32_state(&sbi->s_rnd_state);
+ pr_err("ext4 random: %lu\n", grp);
+ }
parent_group = (unsigned)grp % ngroups;
for (i = 0; i < ngroups; i++) {
g = (parent_group + i) % ngroups;
diff --git a/fs/ext4/mmp.c b/fs/ext4/mmp.c
index 23d436d..99f69dc 100644
--- a/fs/ext4/mmp.c
+++ b/fs/ext4/mmp.c
@@ -258,12 +258,12 @@ exit_thread:
* Get a random new sequence number but make sure it is not greater than
* EXT4_MMP_SEQ_MAX.
*/
-static unsigned int mmp_new_seq(void)
+static unsigned int mmp_new_seq(struct ext4_sb_info *sbi)
{
u32 new_seq;
do {
- new_seq = prandom_u32();
+ new_seq = prandom_u32_state(&sbi->s_rnd_state);
} while (new_seq > EXT4_MMP_SEQ_MAX);
return new_seq;
@@ -342,7 +342,7 @@ skip:
/*
* write a new random sequence number.
*/
- seq = mmp_new_seq();
+ seq = mmp_new_seq(EXT4_SB(sb));
mmp->mmp_seq = cpu_to_le32(seq);
retval = write_mmp_block(sb, bh);
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index c13a4e4..2c86b98 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -2969,7 +2969,7 @@ static struct ext4_li_request *ext4_li_request_new(struct super_block *sb,
* spread the inode table initialization requests
* better.
*/
- elr->lr_next_sched = jiffies + (prandom_u32() %
+ elr->lr_next_sched = jiffies + (prandom_u32_state(&sbi->s_rnd_state) %
(EXT4_DEF_LI_MAX_START_DELAY * HZ));
return elr;
}
@@ -3274,6 +3274,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
if (sb->s_bdev->bd_part)
sbi->s_sectors_written_start =
part_stat_read(sb->s_bdev->bd_part, sectors[1]);
+ _prandom_seed(&sbi->s_rnd_state, 0, true);
/* Cleanup superblock name */
strreplace(sb->s_id, '/', '!');
diff --git a/fs/ext4/sysfs.c b/fs/ext4/sysfs.c
index 1420a3c..f74d34b 100644
--- a/fs/ext4/sysfs.c
+++ b/fs/ext4/sysfs.c
@@ -26,6 +26,7 @@ typedef enum {
attr_feature,
attr_pointer_ui,
attr_pointer_atomic,
+ attr_prandom_seed,
} attr_id_t;
typedef enum {
@@ -90,6 +91,21 @@ static ssize_t inode_readahead_blks_store(struct ext4_attr *a,
return count;
}
+static ssize_t prandom_seed_store(struct ext4_attr *a,
+ struct ext4_sb_info *sbi,
+ const char *buf, size_t count)
+{
+ unsigned long t;
+ int ret;
+
+ ret = kstrtoul(skip_spaces(buf), 0, &t);
+ if (ret)
+ return ret;
+
+ _prandom_seed(&sbi->s_rnd_state, t, false);
+ return count;
+}
+
static ssize_t reserved_clusters_store(struct ext4_attr *a,
struct ext4_sb_info *sbi,
const char *buf, size_t count)
@@ -178,6 +194,7 @@ EXT4_RW_ATTR_SBI_UI(mb_stream_req, s_mb_stream_request);
EXT4_RW_ATTR_SBI_UI(mb_group_prealloc, s_mb_group_prealloc);
EXT4_RW_ATTR_SBI_UI(extent_max_zeroout_kb, s_extent_max_zeroout_kb);
EXT4_ATTR(trigger_fs_error, 0200, trigger_test_error);
+EXT4_ATTR(prandom_seed, 0200, prandom_seed);
EXT4_RW_ATTR_SBI_UI(err_ratelimit_interval_ms, s_err_ratelimit_state.interval);
EXT4_RW_ATTR_SBI_UI(err_ratelimit_burst, s_err_ratelimit_state.burst);
EXT4_RW_ATTR_SBI_UI(warning_ratelimit_interval_ms, s_warning_ratelimit_state.interval);
@@ -216,6 +233,7 @@ static struct attribute *ext4_attrs[] = {
ATTR_LIST(errors_count),
ATTR_LIST(first_error_time),
ATTR_LIST(last_error_time),
+ ATTR_LIST(prandom_seed),
NULL,
};
@@ -313,6 +331,8 @@ static ssize_t ext4_attr_store(struct kobject *kobj,
return inode_readahead_blks_store(a, sbi, buf, len);
case attr_trigger_test_error:
return trigger_test_error(a, sbi, buf, len);
+ case attr_prandom_seed:
+ return prandom_seed_store(a, sbi, buf, len);
}
return 0;
}
diff --git a/include/linux/random.h b/include/linux/random.h
index e47e533..64b70a8 100644
--- a/include/linux/random.h
+++ b/include/linux/random.h
@@ -45,6 +45,7 @@ struct rnd_state {
__u32 s1, s2, s3, s4;
};
+void _prandom_seed(struct rnd_state *state, u32 seed, bool mix_with_hwseed);
u32 prandom_u32_state(struct rnd_state *state);
void prandom_bytes_state(struct rnd_state *state, void *buf, size_t nbytes);
void prandom_seed_full_state(struct rnd_state __percpu *pcpu_state);
diff --git a/lib/random32.c b/lib/random32.c
index 510d1ce..5134111 100644
--- a/lib/random32.c
+++ b/lib/random32.c
@@ -157,8 +157,7 @@ static u32 __extract_hwseed(void)
return val;
}
-static void prandom_seed_early(struct rnd_state *state, u32 seed,
- bool mix_with_hwseed)
+void _prandom_seed(struct rnd_state *state, u32 seed, bool mix_with_hwseed)
{
#define LCG(x) ((x) * 69069U) /* super-duper LCG */
#define HWSEED() (mix_with_hwseed ? __extract_hwseed() : 0)
@@ -167,6 +166,7 @@ static void prandom_seed_early(struct rnd_state *state, u32 seed,
state->s3 = __seed(HWSEED() ^ LCG(state->s2), 16U);
state->s4 = __seed(HWSEED() ^ LCG(state->s3), 128U);
}
+EXPORT_SYMBOL(_prandom_seed);
/**
* prandom_seed - add entropy to pseudo random number generator
@@ -204,7 +204,7 @@ static int __init prandom_init(void)
struct rnd_state *state = &per_cpu(net_rand_state, i);
u32 weak_seed = (i + jiffies) ^ random_get_entropy();
- prandom_seed_early(state, weak_seed, true);
+ _prandom_seed(state, weak_seed, true);
prandom_warmup(state);
}
@@ -429,7 +429,7 @@ static void __init prandom_state_selftest(void)
for (i = 0; i < ARRAY_SIZE(test1); i++) {
struct rnd_state state;
- prandom_seed_early(&state, test1[i].seed, false);
+ _prandom_seed(&state, test1[i].seed, false);
prandom_warmup(&state);
if (test1[i].result != prandom_u32_state(&state))
@@ -444,7 +444,7 @@ static void __init prandom_state_selftest(void)
for (i = 0; i < ARRAY_SIZE(test2); i++) {
struct rnd_state state;
- prandom_seed_early(&state, test2[i].seed, false);
+ _prandom_seed(&state, test2[i].seed, false);
prandom_warmup(&state);
for (j = 0; j < test2[i].iteration - 1; j++)
--
2.9.0.243.g5c589a7.dirty
^ permalink raw reply related [flat|nested] 4+ messages in thread* Re: [PATCH] ext4: add ability to control the pseudo-random seed used by ext4
2016-07-29 16:00 [PATCH] ext4: add ability to control the pseudo-random seed used by ext4 Theodore Ts'o
@ 2016-07-29 18:07 ` kbuild test robot
2016-07-29 19:33 ` kbuild test robot
2016-07-29 19:39 ` kbuild test robot
2 siblings, 0 replies; 4+ messages in thread
From: kbuild test robot @ 2016-07-29 18:07 UTC (permalink / raw)
To: Theodore Ts'o
Cc: kbuild-all, Ext4 Developers List, agayev, Theodore Ts'o
[-- Attachment #1: Type: text/plain, Size: 2082 bytes --]
Hi,
[auto build test WARNING on ext4/dev]
[also build test WARNING on v4.7 next-20160729]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Theodore-Ts-o/ext4-add-ability-to-control-the-pseudo-random-seed-used-by-ext4/20160730-001338
base: https://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4.git dev
config: x86_64-randconfig-s2-07300120 (attached as .config)
compiler: gcc-4.4 (Debian 4.4.7-8) 4.4.7
reproduce:
# save the attached .config to linux build tree
make ARCH=x86_64
All warnings (new ones prefixed by >>):
fs/ext4/ialloc.c: In function 'find_group_orlov':
>> fs/ext4/ialloc.c:490: warning: format '%lu' expects type 'long unsigned int', but argument 2 has type 'ext4_group_t'
fs/ext4/ialloc.c: In function 'ext4_orphan_get':
fs/ext4/ialloc.c:1155: warning: 'bit' may be used uninitialized in this function
vim +490 fs/ext4/ialloc.c
474 do_div(avefreec, ngroups);
475 ndirs = percpu_counter_read_positive(&sbi->s_dirs_counter);
476
477 if (S_ISDIR(mode) &&
478 ((parent == d_inode(sb->s_root)) ||
479 (ext4_test_inode_flag(parent, EXT4_INODE_TOPDIR)))) {
480 int best_ndir = inodes_per_group;
481 int ret = -1;
482
483 if (qstr) {
484 hinfo.hash_version = DX_HASH_HALF_MD4;
485 hinfo.seed = sbi->s_hash_seed;
486 ext4fs_dirhash(qstr->name, qstr->len, &hinfo);
487 grp = hinfo.hash;
488 } else {
489 grp = prandom_u32_state(&sbi->s_rnd_state);
> 490 pr_err("ext4 random: %lu\n", grp);
491 }
492 parent_group = (unsigned)grp % ngroups;
493 for (i = 0; i < ngroups; i++) {
494 g = (parent_group + i) % ngroups;
495 get_orlov_stats(sb, g, flex_size, &stats);
496 if (!stats.free_inodes)
497 continue;
498 if (stats.used_dirs >= best_ndir)
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/octet-stream, Size: 24519 bytes --]
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: [PATCH] ext4: add ability to control the pseudo-random seed used by ext4
2016-07-29 16:00 [PATCH] ext4: add ability to control the pseudo-random seed used by ext4 Theodore Ts'o
2016-07-29 18:07 ` kbuild test robot
@ 2016-07-29 19:33 ` kbuild test robot
2016-07-29 19:39 ` kbuild test robot
2 siblings, 0 replies; 4+ messages in thread
From: kbuild test robot @ 2016-07-29 19:33 UTC (permalink / raw)
To: Theodore Ts'o
Cc: kbuild-all, Ext4 Developers List, agayev, Theodore Ts'o
[-- Attachment #1: Type: text/plain, Size: 2163 bytes --]
Hi,
[auto build test WARNING on ext4/dev]
[also build test WARNING on v4.7 next-20160729]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Theodore-Ts-o/ext4-add-ability-to-control-the-pseudo-random-seed-used-by-ext4/20160730-001338
base: https://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4.git dev
config: m68k-allyesconfig (attached as .config)
compiler: m68k-linux-gcc (GCC) 4.9.0
reproduce:
wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=m68k
All warnings (new ones prefixed by >>):
fs/ext4/ialloc.c: In function 'find_group_orlov':
>> fs/ext4/ialloc.c:490:4: warning: format '%lu' expects argument of type 'long unsigned int', but argument 2 has type 'ext4_group_t' [-Wformat=]
pr_err("ext4 random: %lu\n", grp);
^
vim +490 fs/ext4/ialloc.c
474 do_div(avefreec, ngroups);
475 ndirs = percpu_counter_read_positive(&sbi->s_dirs_counter);
476
477 if (S_ISDIR(mode) &&
478 ((parent == d_inode(sb->s_root)) ||
479 (ext4_test_inode_flag(parent, EXT4_INODE_TOPDIR)))) {
480 int best_ndir = inodes_per_group;
481 int ret = -1;
482
483 if (qstr) {
484 hinfo.hash_version = DX_HASH_HALF_MD4;
485 hinfo.seed = sbi->s_hash_seed;
486 ext4fs_dirhash(qstr->name, qstr->len, &hinfo);
487 grp = hinfo.hash;
488 } else {
489 grp = prandom_u32_state(&sbi->s_rnd_state);
> 490 pr_err("ext4 random: %lu\n", grp);
491 }
492 parent_group = (unsigned)grp % ngroups;
493 for (i = 0; i < ngroups; i++) {
494 g = (parent_group + i) % ngroups;
495 get_orlov_stats(sb, g, flex_size, &stats);
496 if (!stats.free_inodes)
497 continue;
498 if (stats.used_dirs >= best_ndir)
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/octet-stream, Size: 37236 bytes --]
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: [PATCH] ext4: add ability to control the pseudo-random seed used by ext4
2016-07-29 16:00 [PATCH] ext4: add ability to control the pseudo-random seed used by ext4 Theodore Ts'o
2016-07-29 18:07 ` kbuild test robot
2016-07-29 19:33 ` kbuild test robot
@ 2016-07-29 19:39 ` kbuild test robot
2 siblings, 0 replies; 4+ messages in thread
From: kbuild test robot @ 2016-07-29 19:39 UTC (permalink / raw)
To: Theodore Ts'o
Cc: kbuild-all, Ext4 Developers List, agayev, Theodore Ts'o
[-- Attachment #1: Type: text/plain, Size: 3079 bytes --]
Hi,
[auto build test WARNING on ext4/dev]
[also build test WARNING on v4.7 next-20160729]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Theodore-Ts-o/ext4-add-ability-to-control-the-pseudo-random-seed-used-by-ext4/20160730-001338
base: https://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4.git dev
config: sparc64-allyesconfig (attached as .config)
compiler: sparc64-linux-gnu-gcc (Debian 5.4.0-6) 5.4.0 20160609
reproduce:
wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=sparc64
All warnings (new ones prefixed by >>):
In file included from include/linux/printk.h:6:0,
from include/linux/kernel.h:13,
from include/linux/list.h:8,
from include/linux/preempt.h:10,
from include/linux/spinlock.h:50,
from include/linux/seqlock.h:35,
from include/linux/time.h:5,
from fs/ext4/ialloc.c:15:
fs/ext4/ialloc.c: In function 'find_group_orlov':
>> include/linux/kern_levels.h:4:18: warning: format '%lu' expects argument of type 'long unsigned int', but argument 2 has type 'ext4_group_t {aka unsigned int}' [-Wformat=]
#define KERN_SOH "\001" /* ASCII Start Of Header */
^
include/linux/kern_levels.h:10:18: note: in expansion of macro 'KERN_SOH'
#define KERN_ERR KERN_SOH "3" /* error conditions */
^
include/linux/printk.h:264:9: note: in expansion of macro 'KERN_ERR'
printk(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__)
^
>> fs/ext4/ialloc.c:490:4: note: in expansion of macro 'pr_err'
pr_err("ext4 random: %lu\n", grp);
^
vim +/pr_err +490 fs/ext4/ialloc.c
474 do_div(avefreec, ngroups);
475 ndirs = percpu_counter_read_positive(&sbi->s_dirs_counter);
476
477 if (S_ISDIR(mode) &&
478 ((parent == d_inode(sb->s_root)) ||
479 (ext4_test_inode_flag(parent, EXT4_INODE_TOPDIR)))) {
480 int best_ndir = inodes_per_group;
481 int ret = -1;
482
483 if (qstr) {
484 hinfo.hash_version = DX_HASH_HALF_MD4;
485 hinfo.seed = sbi->s_hash_seed;
486 ext4fs_dirhash(qstr->name, qstr->len, &hinfo);
487 grp = hinfo.hash;
488 } else {
489 grp = prandom_u32_state(&sbi->s_rnd_state);
> 490 pr_err("ext4 random: %lu\n", grp);
491 }
492 parent_group = (unsigned)grp % ngroups;
493 for (i = 0; i < ngroups; i++) {
494 g = (parent_group + i) % ngroups;
495 get_orlov_stats(sb, g, flex_size, &stats);
496 if (!stats.free_inodes)
497 continue;
498 if (stats.used_dirs >= best_ndir)
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/octet-stream, Size: 46457 bytes --]
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2016-07-29 19:40 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-07-29 16:00 [PATCH] ext4: add ability to control the pseudo-random seed used by ext4 Theodore Ts'o
2016-07-29 18:07 ` kbuild test robot
2016-07-29 19:33 ` kbuild test robot
2016-07-29 19:39 ` kbuild test robot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox