Move the max_read_ahead_* tunables from debugfs to sysfs, since
they follow the one-value-per-file rule and should be visible to
regular users.
Rename the functions and constants from *readahead* to *read_ahead*
or *READ_AHEAD* to match the tunable names from procfs.
Deprecate usage of llprocfs_str_with_units_to_s64(), lu_str_to_s64(),
llprocfs_str_with_units_to_u64(), and lu_str_to_u64(), and instead
use sysfs_memparse() to parse sizes in the few remaining places
where they are used. A separate patch will remove those functions.
Minor fix to the "lctl set_param" man page.
Fixes:
adb5aca3d673 ("LU-8066 llite: Move all remaining procfs entries to debugfs")
Signed-off-by: Andreas Dilger <adilger@whamcloud.com>
Change-Id: I2cdf5f8f0aeca458ed1989366102c33ae83ebbe5
Reviewed-on: https://review.whamcloud.com/34849
Reviewed-by: James Simmons <jsimmons@infradead.org>
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Wang Shilong <wshilong@ddn.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
LPO64||%#llo
LPPID||%d
lprocfs_str_to_s64||kstrtoxxx_from_user
LPO64||%#llo
LPPID||%d
lprocfs_str_to_s64||kstrtoxxx_from_user
-lprocfs_str_with_units_to_s64||sysfs_memparse
-lu_str_to_s64|sysfs_memparse
+lprocfs_str_with_units_to_u64||sysfs_memparse using sysfs/kernbuf
+lprocfs_str_with_units_to_s64||sysfs_memparse using sysfs/kernbuf
+lu_str_to_s64||sysfs_memparse
LPROC_SEQ_FOPS||LUSTRE_RW_ATTR
LPROC_SEQ_FOPS_RO_TYPE||LUSTRE_RO_ATTR
LPROC_SEQ_FOPS_RO||LUSTRE_RO_ATTR
LPROC_SEQ_FOPS||LUSTRE_RW_ATTR
LPROC_SEQ_FOPS_RO_TYPE||LUSTRE_RO_ATTR
LPROC_SEQ_FOPS_RO||LUSTRE_RO_ATTR
instead of from the command-line. The contents of
.I filename
is YAML format, created as an output from
instead of from the command-line. The contents of
.I filename
is YAML format, created as an output from
-.BR "lctl --device MGS llog_print " < \fIfsname >- client
-fR or any other valid llog configuration log as listed by
-.B lctl --device MGS llog_catlist
+.BR ' "lctl --device MGS llog_print " < \fIfsname\fR >- client '
+or any other valid llog configuration log as listed by
+.RB ' "lctl --device MGS llog_catlist" '
.TP
.B -n
Disable printing of the parameter name after setting it.
.TP
.B -n
Disable printing of the parameter name after setting it.
/* default to use at least 16M for fast read if possible */
#define RA_REMAIN_WINDOW_MIN MiB_TO_PAGES(16UL)
/* default to use at least 16M for fast read if possible */
#define RA_REMAIN_WINDOW_MIN MiB_TO_PAGES(16UL)
-/* default to about 64M of readahead on a given system. */
-#define SBI_DEFAULT_READAHEAD_MAX MiB_TO_PAGES(64UL)
+/* default readahead on a given system. */
+#define SBI_DEFAULT_READ_AHEAD_MAX MiB_TO_PAGES(64UL)
-/* default to read-ahead full files smaller than 2MB on the second read */
-#define SBI_DEFAULT_READAHEAD_WHOLE_MAX MiB_TO_PAGES(2UL)
+/* default read-ahead full files smaller than limit on the second read */
+#define SBI_DEFAULT_READ_AHEAD_WHOLE_MAX MiB_TO_PAGES(2UL)
enum ra_stat {
RA_STAT_HIT = 0,
enum ra_stat {
RA_STAT_HIT = 0,
GOTO(out_destroy_ra, rc = -ENOMEM);
sbi->ll_ra_info.ra_max_pages_per_file = min(pages / 32,
GOTO(out_destroy_ra, rc = -ENOMEM);
sbi->ll_ra_info.ra_max_pages_per_file = min(pages / 32,
- SBI_DEFAULT_READAHEAD_MAX);
+ SBI_DEFAULT_READ_AHEAD_MAX);
sbi->ll_ra_info.ra_async_pages_per_file_threshold =
sbi->ll_ra_info.ra_max_pages_per_file;
sbi->ll_ra_info.ra_max_pages = sbi->ll_ra_info.ra_max_pages_per_file;
sbi->ll_ra_info.ra_async_pages_per_file_threshold =
sbi->ll_ra_info.ra_max_pages_per_file;
sbi->ll_ra_info.ra_max_pages = sbi->ll_ra_info.ra_max_pages_per_file;
/* Don't change value if it was specified in the config log */
if (sbi->ll_ra_info.ra_max_read_ahead_whole_pages == -1) {
sbi->ll_ra_info.ra_max_read_ahead_whole_pages =
/* Don't change value if it was specified in the config log */
if (sbi->ll_ra_info.ra_max_read_ahead_whole_pages == -1) {
sbi->ll_ra_info.ra_max_read_ahead_whole_pages =
- max_t(unsigned long, SBI_DEFAULT_READAHEAD_WHOLE_MAX,
+ max_t(unsigned long, SBI_DEFAULT_READ_AHEAD_WHOLE_MAX,
(data->ocd_brw_size >> PAGE_SHIFT));
if (sbi->ll_ra_info.ra_max_read_ahead_whole_pages >
sbi->ll_ra_info.ra_max_pages_per_file)
(data->ocd_brw_size >> PAGE_SHIFT));
if (sbi->ll_ra_info.ra_max_read_ahead_whole_pages >
sbi->ll_ra_info.ra_max_pages_per_file)
LDEBUGFS_SEQ_FOPS_RO(ll_site_stats);
LDEBUGFS_SEQ_FOPS_RO(ll_site_stats);
-static int ll_max_readahead_mb_seq_show(struct seq_file *m, void *v)
+static ssize_t max_read_ahead_mb_show(struct kobject *kobj,
+ struct attribute *attr, char *buf)
- struct super_block *sb = m->private;
- struct ll_sb_info *sbi = ll_s2sbi(sb);
+ struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info,
+ ll_kset.kobj);
unsigned long ra_max_mb;
spin_lock(&sbi->ll_lock);
ra_max_mb = PAGES_TO_MiB(sbi->ll_ra_info.ra_max_pages);
spin_unlock(&sbi->ll_lock);
unsigned long ra_max_mb;
spin_lock(&sbi->ll_lock);
ra_max_mb = PAGES_TO_MiB(sbi->ll_ra_info.ra_max_pages);
spin_unlock(&sbi->ll_lock);
- seq_printf(m, "%lu\n", ra_max_mb);
- return 0;
+ return snprintf(buf, PAGE_SIZE, "%lu\n", ra_max_mb);
-static ssize_t
-ll_max_readahead_mb_seq_write(struct file *file, const char __user *buffer,
- size_t count, loff_t *off)
+static ssize_t max_read_ahead_mb_store(struct kobject *kobj,
+ struct attribute *attr,
+ const char *buffer, size_t count)
- struct seq_file *m = file->private_data;
- struct super_block *sb = m->private;
- struct ll_sb_info *sbi = ll_s2sbi(sb);
- s64 ra_max_mb, pages_number;
+ struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info,
+ ll_kset.kobj);
+ u64 ra_max_mb, pages_number;
- rc = lprocfs_str_with_units_to_s64(buffer, count, &ra_max_mb, 'M');
+ rc = sysfs_memparse(buffer, count, &ra_max_mb, "MiB");
if (rc)
return rc;
pages_number = round_up(ra_max_mb, 1024 * 1024) >> PAGE_SHIFT;
if (rc)
return rc;
pages_number = round_up(ra_max_mb, 1024 * 1024) >> PAGE_SHIFT;
- if (pages_number < 0 || pages_number > cfs_totalram_pages() / 2) {
+ CDEBUG(D_INFO, "%s: set max_read_ahead_mb=%llu (%llu pages)\n",
+ sbi->ll_fsname, PAGES_TO_MiB(pages_number), pages_number);
+ if (pages_number > cfs_totalram_pages() / 2) {
- CERROR("%s: can't set max_readahead_mb=%llu > %luMB\n",
+ CERROR("%s: cannot set max_read_ahead_mb=%llu > totalram/2=%luMB\n",
sbi->ll_fsname, PAGES_TO_MiB(pages_number),
sbi->ll_fsname, PAGES_TO_MiB(pages_number),
- PAGES_TO_MiB(cfs_totalram_pages()));
+ PAGES_TO_MiB(cfs_totalram_pages() / 2));
+LUSTRE_RW_ATTR(max_read_ahead_mb);
-LDEBUGFS_SEQ_FOPS(ll_max_readahead_mb);
-
-static int ll_max_readahead_per_file_mb_seq_show(struct seq_file *m, void *v)
+static ssize_t max_read_ahead_per_file_mb_show(struct kobject *kobj,
+ struct attribute *attr,
+ char *buf)
- struct super_block *sb = m->private;
- struct ll_sb_info *sbi = ll_s2sbi(sb);
+ struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info,
+ ll_kset.kobj);
unsigned long ra_max_file_mb;
spin_lock(&sbi->ll_lock);
ra_max_file_mb = PAGES_TO_MiB(sbi->ll_ra_info.ra_max_pages_per_file);
spin_unlock(&sbi->ll_lock);
unsigned long ra_max_file_mb;
spin_lock(&sbi->ll_lock);
ra_max_file_mb = PAGES_TO_MiB(sbi->ll_ra_info.ra_max_pages_per_file);
spin_unlock(&sbi->ll_lock);
- seq_printf(m, "%lu\n", ra_max_file_mb);
- return 0;
+ return snprintf(buf, PAGE_SIZE, "%lu\n", ra_max_file_mb);
-static ssize_t
-ll_max_readahead_per_file_mb_seq_write(struct file *file,
- const char __user *buffer,
- size_t count, loff_t *off)
+static ssize_t max_read_ahead_per_file_mb_store(struct kobject *kobj,
+ struct attribute *attr,
+ const char *buffer,
+ size_t count)
- struct seq_file *m = file->private_data;
- struct super_block *sb = m->private;
- struct ll_sb_info *sbi = ll_s2sbi(sb);
- s64 ra_max_file_mb, pages_number;
+ struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info,
+ ll_kset.kobj);
+ u64 ra_max_file_mb, pages_number;
- rc = lprocfs_str_with_units_to_s64(buffer, count, &ra_max_file_mb,
- 'M');
+ rc = sysfs_memparse(buffer, count, &ra_max_file_mb, "MiB");
if (rc)
return rc;
pages_number = round_up(ra_max_file_mb, 1024 * 1024) >> PAGE_SHIFT;
if (rc)
return rc;
pages_number = round_up(ra_max_file_mb, 1024 * 1024) >> PAGE_SHIFT;
- if (pages_number < 0 || pages_number > sbi->ll_ra_info.ra_max_pages) {
- CERROR("%s: can't set max_readahead_per_file_mb=%llu > max_read_ahead_mb=%lu\n",
+ if (pages_number > sbi->ll_ra_info.ra_max_pages) {
+ CERROR("%s: cannot set max_read_ahead_per_file_mb=%llu > max_read_ahead_mb=%lu\n",
sbi->ll_fsname, PAGES_TO_MiB(pages_number),
PAGES_TO_MiB(sbi->ll_ra_info.ra_max_pages));
return -ERANGE;
sbi->ll_fsname, PAGES_TO_MiB(pages_number),
PAGES_TO_MiB(sbi->ll_ra_info.ra_max_pages));
return -ERANGE;
+LUSTRE_RW_ATTR(max_read_ahead_per_file_mb);
-LDEBUGFS_SEQ_FOPS(ll_max_readahead_per_file_mb);
-
-static int ll_max_read_ahead_whole_mb_seq_show(struct seq_file *m, void *v)
+static ssize_t max_read_ahead_whole_mb_show(struct kobject *kobj,
+ struct attribute *attr, char *buf)
- struct super_block *sb = m->private;
- struct ll_sb_info *sbi = ll_s2sbi(sb);
+ struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info,
+ ll_kset.kobj);
unsigned long ra_max_whole_mb;
spin_lock(&sbi->ll_lock);
ra_max_whole_mb = PAGES_TO_MiB(sbi->ll_ra_info.ra_max_read_ahead_whole_pages);
spin_unlock(&sbi->ll_lock);
unsigned long ra_max_whole_mb;
spin_lock(&sbi->ll_lock);
ra_max_whole_mb = PAGES_TO_MiB(sbi->ll_ra_info.ra_max_read_ahead_whole_pages);
spin_unlock(&sbi->ll_lock);
- seq_printf(m, "%lu\n", ra_max_whole_mb);
- return 0;
+ return snprintf(buf, PAGE_SIZE, "%lu\n", ra_max_whole_mb);
-static ssize_t
-ll_max_read_ahead_whole_mb_seq_write(struct file *file,
- const char __user *buffer,
- size_t count, loff_t *off)
+static ssize_t max_read_ahead_whole_mb_store(struct kobject *kobj,
+ struct attribute *attr,
+ const char *buffer, size_t count)
- struct seq_file *m = file->private_data;
- struct super_block *sb = m->private;
- struct ll_sb_info *sbi = ll_s2sbi(sb);
- s64 ra_max_whole_mb, pages_number;
+ struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info,
+ ll_kset.kobj);
+ u64 ra_max_whole_mb, pages_number;
- rc = lprocfs_str_with_units_to_s64(buffer, count, &ra_max_whole_mb,
- 'M');
+ rc = sysfs_memparse(buffer, count, &ra_max_whole_mb, "MiB");
/* Cap this at the current max readahead window size, the readahead
* algorithm does this anyway so it's pointless to set it larger.
*/
/* Cap this at the current max readahead window size, the readahead
* algorithm does this anyway so it's pointless to set it larger.
*/
- if (pages_number < 0 ||
- pages_number > sbi->ll_ra_info.ra_max_pages_per_file) {
- CERROR("%s: can't set max_read_ahead_whole_mb=%llu > max_read_ahead_per_file_mb=%lu\n",
+ if (pages_number > sbi->ll_ra_info.ra_max_pages_per_file) {
+ CERROR("%s: cannot set max_read_ahead_whole_mb=%llu > max_read_ahead_per_file_mb=%lu\n",
sbi->ll_fsname, PAGES_TO_MiB(pages_number),
PAGES_TO_MiB(sbi->ll_ra_info.ra_max_pages_per_file));
sbi->ll_fsname, PAGES_TO_MiB(pages_number),
PAGES_TO_MiB(sbi->ll_ra_info.ra_max_pages_per_file));
-
-LDEBUGFS_SEQ_FOPS(ll_max_read_ahead_whole_mb);
+LUSTRE_RW_ATTR(max_read_ahead_whole_mb);
static int ll_max_cached_mb_seq_show(struct seq_file *m, void *v)
{
static int ll_max_cached_mb_seq_show(struct seq_file *m, void *v)
{
long diff = 0;
long nrpages = 0;
__u16 refcheck;
long diff = 0;
long nrpages = 0;
__u16 refcheck;
+ char kernbuf[128], *ptr;
ENTRY;
if (count >= sizeof(kernbuf))
ENTRY;
if (count >= sizeof(kernbuf))
if (copy_from_user(kernbuf, buffer, count))
RETURN(-EFAULT);
if (copy_from_user(kernbuf, buffer, count))
RETURN(-EFAULT);
- buffer += lprocfs_find_named_value(kernbuf, "max_cached_mb:", &count) -
- kernbuf;
- rc = lprocfs_str_with_units_to_s64(buffer, count, &pages_number, 'M');
+ ptr = lprocfs_find_named_value(kernbuf, "max_cached_mb:", &count);
+ rc = sysfs_memparse(ptr, count, &pages_number, "MiB");
LDEBUGFS_SEQ_FOPS(ll_max_cached_mb);
static ssize_t checksums_show(struct kobject *kobj, struct attribute *attr,
LDEBUGFS_SEQ_FOPS(ll_max_cached_mb);
static ssize_t checksums_show(struct kobject *kobj, struct attribute *attr,
}
static ssize_t max_read_ahead_async_active_store(struct kobject *kobj,
}
static ssize_t max_read_ahead_async_active_store(struct kobject *kobj,
- struct attribute *attr,
- const char *buffer,
- size_t count)
+ struct attribute *attr,
+ const char *buffer,
+ size_t count)
- unsigned int val;
- int rc;
struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info,
ll_kset.kobj);
struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info,
ll_kset.kobj);
+ unsigned int val;
+ int rc;
rc = kstrtouint(buffer, 10, &val);
if (rc)
rc = kstrtouint(buffer, 10, &val);
if (rc)
+ spin_lock(&sbi->ll_lock);
sbi->ll_ra_info.ra_async_max_active = val;
sbi->ll_ra_info.ra_async_max_active = val;
+ spin_unlock(&sbi->ll_lock);
workqueue_set_max_active(sbi->ll_ra_info.ll_readahead_wq, val);
return count;
workqueue_set_max_active(sbi->ll_ra_info.ll_readahead_wq, val);
return count;
struct lprocfs_vars lprocfs_llite_obd_vars[] = {
{ .name = "site",
.fops = &ll_site_stats_fops },
struct lprocfs_vars lprocfs_llite_obd_vars[] = {
{ .name = "site",
.fops = &ll_site_stats_fops },
- { .name = "max_read_ahead_mb",
- .fops = &ll_max_readahead_mb_fops },
- { .name = "max_read_ahead_per_file_mb",
- .fops = &ll_max_readahead_per_file_mb_fops },
- { .name = "max_read_ahead_whole_mb",
- .fops = &ll_max_read_ahead_whole_mb_fops },
{ .name = "max_cached_mb",
.fops = &ll_max_cached_mb_fops },
{ .name = "statahead_stats",
{ .name = "max_cached_mb",
.fops = &ll_max_cached_mb_fops },
{ .name = "statahead_stats",
&lustre_attr_uuid.attr,
&lustre_attr_checksums.attr,
&lustre_attr_checksum_pages.attr,
&lustre_attr_uuid.attr,
&lustre_attr_checksums.attr,
&lustre_attr_checksum_pages.attr,
+ &lustre_attr_max_read_ahead_mb.attr,
+ &lustre_attr_max_read_ahead_per_file_mb.attr,
+ &lustre_attr_max_read_ahead_whole_mb.attr,
+ &lustre_attr_max_read_ahead_async_active.attr,
+ &lustre_attr_read_ahead_async_file_threshold_mb.attr,
&lustre_attr_stats_track_pid.attr,
&lustre_attr_stats_track_ppid.attr,
&lustre_attr_stats_track_gid.attr,
&lustre_attr_stats_track_pid.attr,
&lustre_attr_stats_track_ppid.attr,
&lustre_attr_stats_track_gid.attr,
&lustre_attr_file_heat.attr,
&lustre_attr_heat_decay_percentage.attr,
&lustre_attr_heat_period_second.attr,
&lustre_attr_file_heat.attr,
&lustre_attr_heat_decay_percentage.attr,
&lustre_attr_heat_period_second.attr,
- &lustre_attr_max_read_ahead_async_active.attr,
- &lustre_attr_read_ahead_async_file_threshold_mb.attr,
struct obd_import *imp;
struct obd_connect_data *ocd;
int chunk_mask, rc;
struct obd_import *imp;
struct obd_connect_data *ocd;
int chunk_mask, rc;
+ char kernbuf[22];
+ u64 val;
+
+ if (count > sizeof(kernbuf) - 1)
+ return -EINVAL;
- rc = lprocfs_str_with_units_to_s64(buffer, count, &val, '1');
+ if (copy_from_user(kernbuf, buffer, count))
+ return -EFAULT;
+
+ kernbuf[count] = '\0';
+
+ rc = sysfs_memparse(kernbuf, count, &val, "B");
- if (val < 0)
- return -ERANGE;
/* if the max_pages is specified in bytes, convert to pages */
if (val >= ONE_MB_BRW_SIZE)
/* if the max_pages is specified in bytes, convert to pages */
if (val >= ONE_MB_BRW_SIZE)
struct obd_device *dev = container_of(kobj, struct obd_device,
obd_kset.kobj);
struct client_obd *cli = &dev->u.cli;
struct obd_device *dev = container_of(kobj, struct obd_device,
obd_kset.kobj);
struct client_obd *cli = &dev->u.cli;
- char kernbuf[32];
- s64 val;
- if (count >= sizeof(kernbuf))
- return -EINVAL;
-
- memcpy(kernbuf, buffer, count);
- kernbuf[count] = '\0';
- rc = lu_str_to_s64(kernbuf, count, &val, '1');
- if (rc)
- GOTO(out, rc);
-
- if (val == -1)
+ if (strcmp(buffer, "-1") == 0) {
val = OBD_DEF_SHORT_IO_BYTES;
val = OBD_DEF_SHORT_IO_BYTES;
+ } else {
+ rc = sysfs_memparse(buffer, count, &val, "B");
+ if (rc)
+ GOTO(out, rc);
+ }
if (val && (val < MIN_SHORT_IO_BYTES || val > LNET_MTU))
GOTO(out, rc = -ERANGE);
if (val && (val < MIN_SHORT_IO_BYTES || val > LNET_MTU))
GOTO(out, rc = -ERANGE);
}
run_test 101c "check stripe_size aligned read-ahead ================="
}
run_test 101c "check stripe_size aligned read-ahead ================="
-set_read_ahead() {
- $LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1
- $LCTL set_param -n llite.*.max_read_ahead_mb $1 > /dev/null 2>&1
-}
-
test_101d() {
[ $PARALLEL == "yes" ] && skip "skip parallel run"
test_101d() {
[ $PARALLEL == "yes" ] && skip "skip parallel run"
cancel_lru_locks osc
echo Disable read-ahead
cancel_lru_locks osc
echo Disable read-ahead
- local old_READAHEAD=$(set_read_ahead 0)
+ local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
+ $LCTL set_param -n llite.*.max_read_ahead_mb=0
+ stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_RA" EXIT
+ $LCTL get_param -n llite.*.max_read_ahead_mb
echo Reading the test file $file with read-ahead disabled
local raOFF=$(do_and_time "dd if=$file of=/dev/null bs=1M count=$sz_MB")
echo Reading the test file $file with read-ahead disabled
local raOFF=$(do_and_time "dd if=$file of=/dev/null bs=1M count=$sz_MB")
echo Cancel LRU locks on lustre client to flush the client cache
cancel_lru_locks osc
echo Enable read-ahead with ${ra_MB}MB
echo Cancel LRU locks on lustre client to flush the client cache
cancel_lru_locks osc
echo Enable read-ahead with ${ra_MB}MB
+ $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
echo Reading the test file $file with read-ahead enabled
local raON=$(do_and_time "dd if=$file of=/dev/null bs=1M count=$sz_MB")
echo Reading the test file $file with read-ahead enabled
local raON=$(do_and_time "dd if=$file of=/dev/null bs=1M count=$sz_MB")
echo "read-ahead disabled time read $raOFF"
echo "read-ahead enabled time read $raON"
echo "read-ahead disabled time read $raOFF"
echo "read-ahead enabled time read $raON"
- set_read_ahead $old_READAHEAD
rm -f $file
wait_delete_completed
rm -f $file
wait_delete_completed
save_writethrough $p
set_cache writethrough on
save_writethrough $p
set_cache writethrough on
- local pages_per_rpc=$($LCTL get_param \
- osc.*.max_pages_per_rpc)
+ local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
local at_max=$($LCTL get_param -n at_max)
local timeout=$($LCTL get_param -n timeout)
local test_at="at_max"
local at_max=$($LCTL get_param -n at_max)
local timeout=$($LCTL get_param -n timeout)
local test_at="at_max"