Whamcloud - gitweb
LU-11157 obd: round values to nearest MiB for *_mb syfs files 17/34317/16
authorJames Simmons <uja.ornl@yahoo.com>
Tue, 30 Apr 2019 13:17:56 +0000 (09:17 -0400)
committerOleg Drokin <green@whamcloud.com>
Fri, 10 May 2019 07:12:15 +0000 (07:12 +0000)
Several sysfs files report their settings with the functions
lprocfs_[seq]_read_frac_helper() which has the intent of showing
fractional values i.e 1.5 MiB. This approach has caused problems
with shells which don't handle fractional representation and the
values reported don't faithfully represent the original value the
configurator passed into the sysfs file. To resolve this lets
instead always round up the value the configurator passed into
the sysfs file to the nearest MiB value. This way it is always
guaranteed the values reported are always exactly some MiB value.

Change-Id: Ia2e8cf8421784853aa33d4bb87c54aee00953835
Signed-off-by: James Simmons <uja.ornl@yahoo.com>
Reviewed-on: https://review.whamcloud.com/34317
Reviewed-by: Ben Evans <bevans@cray.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Tested-by: Jenkins
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/include/lprocfs_status.h
lustre/llite/llite_internal.h
lustre/llite/lproc_llite.c
lustre/mdc/lproc_mdc.c
lustre/obdclass/lprocfs_status.c
lustre/osc/lproc_osc.c

index 3da912c..e9d51e6 100644 (file)
@@ -63,6 +63,9 @@ static inline unsigned int pct(unsigned long a, unsigned long b)
        return b ? a * 100 / b : 0;
 }
 
+#define PAGES_TO_MiB(pages)    ((pages) >> (20 - PAGE_SHIFT))
+#define MiB_TO_PAGES(mb)       ((mb) << (20 - PAGE_SHIFT))
+
 /**
  * Append a space separated list of current set flags to str.
  */
@@ -609,9 +612,6 @@ extern ssize_t
 lprocfs_pinger_recov_seq_write(struct file *file, const char __user *buffer,
                               size_t count, loff_t *off);
 
-extern int lprocfs_seq_read_frac_helper(struct seq_file *m, long val, int mult);
-extern int lprocfs_read_frac_helper(char *buffer, unsigned long count,
-                                    long val, int mult);
 extern int lprocfs_str_with_units_to_s64(const char __user *buffer,
                                         unsigned long count, __s64 *val,
                                         char defunit);
index 4a59769..1315c5f 100644 (file)
@@ -338,18 +338,16 @@ int ll_listsecurity(struct inode *inode, char *secctx_name,
 void ll_inode_size_lock(struct inode *inode);
 void ll_inode_size_unlock(struct inode *inode);
 
-// FIXME: replace the name of this with LL_I to conform to kernel stuff
-// static inline struct ll_inode_info *LL_I(struct inode *inode)
 static inline struct ll_inode_info *ll_i2info(struct inode *inode)
 {
-        return container_of(inode, struct ll_inode_info, lli_vfs_inode);
+       return container_of(inode, struct ll_inode_info, lli_vfs_inode);
 }
 
 /* default to about 64M of readahead on a given system. */
-#define SBI_DEFAULT_READAHEAD_MAX      (64UL << (20 - PAGE_SHIFT))
+#define SBI_DEFAULT_READAHEAD_MAX              MiB_TO_PAGES(64UL)
 
 /* default to read-ahead full files smaller than 2MB on the second read */
-#define SBI_DEFAULT_READAHEAD_WHOLE_MAX        (2UL << (20 - PAGE_SHIFT))
+#define SBI_DEFAULT_READAHEAD_WHOLE_MAX                MiB_TO_PAGES(2UL)
 
 enum ra_stat {
         RA_STAT_HIT = 0,
index c177569..5030e0f 100644 (file)
@@ -326,15 +326,14 @@ static int ll_max_readahead_mb_seq_show(struct seq_file *m, void *v)
 {
        struct super_block *sb = m->private;
        struct ll_sb_info *sbi = ll_s2sbi(sb);
-       long pages_number;
-       int mult;
+       unsigned long ra_max_mb;
 
        spin_lock(&sbi->ll_lock);
-       pages_number = sbi->ll_ra_info.ra_max_pages;
+       ra_max_mb = PAGES_TO_MiB(sbi->ll_ra_info.ra_max_pages);
        spin_unlock(&sbi->ll_lock);
 
-       mult = 1 << (20 - PAGE_SHIFT);
-       return lprocfs_seq_read_frac_helper(m, pages_number, mult);
+       seq_printf(m, "%lu\n", ra_max_mb);
+       return 0;
 }
 
 static ssize_t
@@ -344,21 +343,19 @@ ll_max_readahead_mb_seq_write(struct file *file, const char __user *buffer,
        struct seq_file *m = file->private_data;
        struct super_block *sb = m->private;
        struct ll_sb_info *sbi = ll_s2sbi(sb);
-       __s64 pages_number;
+       s64 ra_max_mb, pages_number;
        int rc;
 
-       rc = lprocfs_str_with_units_to_s64(buffer, count, &pages_number, 'M');
+       rc = lprocfs_str_with_units_to_s64(buffer, count, &ra_max_mb, 'M');
        if (rc)
                return rc;
 
-       pages_number >>= PAGE_SHIFT;
-
+       pages_number = round_up(ra_max_mb, 1024 * 1024) >> PAGE_SHIFT;
        if (pages_number < 0 || pages_number > totalram_pages / 2) {
                /* 1/2 of RAM */
-               CERROR("%s: can't set max_readahead_mb=%lu > %luMB\n",
-                      sbi->ll_fsname,
-                      (unsigned long)pages_number >> (20 - PAGE_SHIFT),
-                      totalram_pages >> (20 - PAGE_SHIFT + 1));
+               CERROR("%s: can't set max_readahead_mb=%llu > %luMB\n",
+                      sbi->ll_fsname, PAGES_TO_MiB(pages_number),
+                      PAGES_TO_MiB(totalram_pages));
                return -ERANGE;
        }
 
@@ -375,15 +372,14 @@ static int ll_max_readahead_per_file_mb_seq_show(struct seq_file *m, void *v)
 {
        struct super_block *sb = m->private;
        struct ll_sb_info *sbi = ll_s2sbi(sb);
-       long pages_number;
-       int mult;
+       unsigned long ra_max_file_mb;
 
        spin_lock(&sbi->ll_lock);
-       pages_number = sbi->ll_ra_info.ra_max_pages_per_file;
+       ra_max_file_mb = PAGES_TO_MiB(sbi->ll_ra_info.ra_max_pages_per_file);
        spin_unlock(&sbi->ll_lock);
 
-       mult = 1 << (20 - PAGE_SHIFT);
-       return lprocfs_seq_read_frac_helper(m, pages_number, mult);
+       seq_printf(m, "%lu\n", ra_max_file_mb);
+       return 0;
 }
 
 static ssize_t
@@ -394,20 +390,19 @@ ll_max_readahead_per_file_mb_seq_write(struct file *file,
        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;
        int rc;
-       __s64 pages_number;
 
-       rc = lprocfs_str_with_units_to_s64(buffer, count, &pages_number, 'M');
+       rc = lprocfs_str_with_units_to_s64(buffer, count, &ra_max_file_mb,
+                                          'M');
        if (rc)
                return rc;
 
-       pages_number >>= PAGE_SHIFT;
-
+       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=%lu > "
-                      "max_read_ahead_mb=%lu\n", sbi->ll_fsname,
-                      (unsigned long)pages_number >> (20 - PAGE_SHIFT),
-                      sbi->ll_ra_info.ra_max_pages >> (20 - PAGE_SHIFT));
+               CERROR("%s: can't set max_readahead_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;
        }
 
@@ -424,15 +419,14 @@ static int ll_max_read_ahead_whole_mb_seq_show(struct seq_file *m, void *v)
 {
        struct super_block *sb = m->private;
        struct ll_sb_info *sbi = ll_s2sbi(sb);
-       long pages_number;
-       int mult;
+       unsigned long ra_max_whole_mb;
 
        spin_lock(&sbi->ll_lock);
-       pages_number = sbi->ll_ra_info.ra_max_read_ahead_whole_pages;
+       ra_max_whole_mb = PAGES_TO_MiB(sbi->ll_ra_info.ra_max_read_ahead_whole_pages);
        spin_unlock(&sbi->ll_lock);
 
-       mult = 1 << (20 - PAGE_SHIFT);
-       return lprocfs_seq_read_frac_helper(m, pages_number, mult);
+       seq_printf(m, "%lu\n", ra_max_whole_mb);
+       return 0;
 }
 
 static ssize_t
@@ -443,25 +437,23 @@ ll_max_read_ahead_whole_mb_seq_write(struct file *file,
        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;
        int rc;
-       __s64 pages_number;
 
-       rc = lprocfs_str_with_units_to_s64(buffer, count, &pages_number, 'M');
+       rc = lprocfs_str_with_units_to_s64(buffer, count, &ra_max_whole_mb,
+                                          'M');
        if (rc)
                return rc;
 
-       pages_number >>= PAGE_SHIFT;
-
+       pages_number = round_up(ra_max_whole_mb, 1024 * 1024) >> PAGE_SHIFT;
        /* Cap this at the current max readahead window size, the readahead
-        * algorithm does this anyway so it's pointless to set it larger. */
+        * 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) {
-               int pages_shift = 20 - PAGE_SHIFT;
-               CERROR("%s: can't set max_read_ahead_whole_mb=%lu > "
-                      "max_read_ahead_per_file_mb=%lu\n",
-                      sbi->ll_fsname,
-                      (unsigned long)pages_number >> pages_shift,
-                      sbi->ll_ra_info.ra_max_pages_per_file >> pages_shift);
+               CERROR("%s: can't 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));
                return -ERANGE;
        }
 
@@ -479,12 +471,11 @@ static int ll_max_cached_mb_seq_show(struct seq_file *m, void *v)
        struct super_block     *sb    = m->private;
        struct ll_sb_info      *sbi   = ll_s2sbi(sb);
        struct cl_client_cache *cache = sbi->ll_cache;
-       int shift = 20 - PAGE_SHIFT;
        long max_cached_mb;
        long unused_mb;
 
-       max_cached_mb = cache->ccc_lru_max >> shift;
-       unused_mb = atomic_long_read(&cache->ccc_lru_left) >> shift;
+       max_cached_mb = PAGES_TO_MiB(cache->ccc_lru_max);
+       unused_mb = PAGES_TO_MiB(atomic_long_read(&cache->ccc_lru_left));
        seq_printf(m, "users: %d\n"
                      "max_cached_mb: %ld\n"
                      "used_mb: %ld\n"
@@ -533,7 +524,7 @@ static ssize_t ll_max_cached_mb_seq_write(struct file *file,
        if (pages_number < 0 || pages_number > totalram_pages) {
                CERROR("%s: can't set max cache more than %lu MB\n",
                       sbi->ll_fsname,
-                      totalram_pages >> (20 - PAGE_SHIFT));
+                      PAGES_TO_MiB(totalram_pages));
                RETURN(-ERANGE);
        }
        /* Allow enough cache so clients can make well-formed RPCs */
index 1530dd1..601806a 100644 (file)
@@ -149,15 +149,14 @@ static int mdc_max_dirty_mb_seq_show(struct seq_file *m, void *v)
 {
        struct obd_device *dev = m->private;
        struct client_obd *cli = &dev->u.cli;
-       long val;
-       int mult;
+       unsigned long val;
 
        spin_lock(&cli->cl_loi_list_lock);
-       val = cli->cl_dirty_max_pages;
+       val = PAGES_TO_MiB(cli->cl_dirty_max_pages);
        spin_unlock(&cli->cl_loi_list_lock);
 
-       mult = 1 << (20 - PAGE_SHIFT);
-       return lprocfs_seq_read_frac_helper(m, val, mult);
+       seq_printf(m, "%lu\n", val);
+       return 0;
 }
 
 static ssize_t mdc_max_dirty_mb_seq_write(struct file *file,
@@ -174,10 +173,10 @@ static ssize_t mdc_max_dirty_mb_seq_write(struct file *file,
        if (rc)
                return rc;
 
-       pages_number >>= PAGE_SHIFT;
-
+       /* MB -> pages */
+       pages_number = round_up(pages_number, 1024 * 1024) >> PAGE_SHIFT;
        if (pages_number <= 0 ||
-           pages_number >= OSC_MAX_DIRTY_MB_MAX << (20 - PAGE_SHIFT) ||
+           pages_number >= MiB_TO_PAGES(OSC_MAX_DIRTY_MB_MAX) ||
            pages_number > totalram_pages / 4) /* 1/4 of RAM */
                return -ERANGE;
 
index 6c5d61f..2e28262 100644 (file)
@@ -1772,86 +1772,6 @@ __s64 lprocfs_read_helper(struct lprocfs_counter *lc,
 }
 EXPORT_SYMBOL(lprocfs_read_helper);
 
-int lprocfs_read_frac_helper(char *buffer, unsigned long count, long val,
-                             int mult)
-{
-       long decimal_val, frac_val;
-       int prtn;
-
-       if (count < 10)
-               return -EINVAL;
-
-       decimal_val = val / mult;
-       prtn = snprintf(buffer, count, "%ld", decimal_val);
-       frac_val = val % mult;
-
-       if (prtn < (count - 4) && frac_val > 0) {
-               long temp_frac;
-               int i, temp_mult = 1, frac_bits = 0;
-
-               temp_frac = frac_val * 10;
-               buffer[prtn++] = '.';
-               while (frac_bits < 2 && (temp_frac / mult) < 1) {
-                       /* only reserved 2 bits fraction */
-                       buffer[prtn++] = '0';
-                       temp_frac *= 10;
-                       frac_bits++;
-               }
-               /*
-                * Need to think these cases :
-                *      1. #echo x.00 > /proc/xxx       output result : x
-                *      2. #echo x.0x > /proc/xxx       output result : x.0x
-                *      3. #echo x.x0 > /proc/xxx       output result : x.x
-                *      4. #echo x.xx > /proc/xxx       output result : x.xx
-                *      Only reserved 2 bits fraction.
-                */
-               for (i = 0; i < (5 - prtn); i++)
-                       temp_mult *= 10;
-
-               frac_bits = min((int)count - prtn, 3 - frac_bits);
-               prtn += snprintf(buffer + prtn, frac_bits, "%ld",
-                                frac_val * temp_mult / mult);
-
-               prtn--;
-               while (buffer[prtn] < '1' || buffer[prtn] > '9') {
-                       prtn--;
-                       if (buffer[prtn] == '.') {
-                               prtn--;
-                               break;
-                       }
-               }
-               prtn++;
-       }
-       buffer[prtn++] = '\n';
-       return prtn;
-}
-EXPORT_SYMBOL(lprocfs_read_frac_helper);
-
-int lprocfs_seq_read_frac_helper(struct seq_file *m, long val, int mult)
-{
-       long decimal_val, frac_val;
-
-       decimal_val = val / mult;
-       seq_printf(m, "%ld", decimal_val);
-       frac_val = val % mult;
-
-       if (frac_val > 0) {
-               frac_val *= 100;
-               frac_val /= mult;
-       }
-       if (frac_val > 0) {
-               /* Three cases: x0, xx, 0x */
-               if ((frac_val % 10) != 0)
-                       seq_printf(m, ".%ld", frac_val);
-               else
-                       seq_printf(m, ".%ld", frac_val / 10);
-       }
-
-       seq_printf(m, "\n");
-       return 0;
-}
-EXPORT_SYMBOL(lprocfs_seq_read_frac_helper);
-
 /* Obtains the conversion factor for the unit specified */
 static int get_mult(char unit, __u64 *mult)
 {
index 7b776f7..0db33e2 100644 (file)
@@ -143,16 +143,14 @@ static ssize_t max_dirty_mb_show(struct kobject *kobj,
 {
        struct obd_device *dev = container_of(kobj, struct obd_device,
                                              obd_kset.kobj);
-        struct client_obd *cli = &dev->u.cli;
-        long val;
-        int mult;
+       struct client_obd *cli = &dev->u.cli;
+       unsigned long val;
 
        spin_lock(&cli->cl_loi_list_lock);
-       val = cli->cl_dirty_max_pages;
+       val = PAGES_TO_MiB(cli->cl_dirty_max_pages);
        spin_unlock(&cli->cl_loi_list_lock);
 
-       mult = 1 << (20 - PAGE_SHIFT);
-       return lprocfs_read_frac_helper(buf, PAGE_SIZE, val, mult);
+       return sprintf(buf, "%lu\n", val);
 }
 
 static ssize_t max_dirty_mb_store(struct kobject *kobj,
@@ -163,17 +161,16 @@ static ssize_t max_dirty_mb_store(struct kobject *kobj,
        struct obd_device *dev = container_of(kobj, struct obd_device,
                                              obd_kset.kobj);
        struct client_obd *cli = &dev->u.cli;
-       unsigned long pages_number;
+       unsigned long pages_number, max_dirty_mb;
        int rc;
 
-       rc = kstrtoul(buffer, 10, &pages_number);
+       rc = kstrtoul(buffer, 10, &max_dirty_mb);
        if (rc)
                return rc;
 
-       pages_number *= 1 << (20 - PAGE_SHIFT); /* MB -> pages */
+       pages_number = MiB_TO_PAGES(max_dirty_mb);
 
-       if (pages_number <= 0 ||
-           pages_number >= OSC_MAX_DIRTY_MB_MAX << (20 - PAGE_SHIFT) ||
+       if (pages_number >= MiB_TO_PAGES(OSC_MAX_DIRTY_MB_MAX) ||
            pages_number > totalram_pages / 4) /* 1/4 of RAM */
                return -ERANGE;