s390/dasd: cleanup profiling
authorSebastian Ott <sebott@linux.vnet.ibm.com>
Wed, 28 Jan 2015 18:06:29 +0000 (19:06 +0100)
committerMartin Schwidefsky <schwidefsky@de.ibm.com>
Thu, 29 Jan 2015 08:19:29 +0000 (09:19 +0100)
The dasd driver has a lot of duplicated code to handle
dasd_global_profile. With this patch we use the same code for the
global and the per device profiling data. Note that dasd_stats_write
had to change slightly to maintain some odd differences between
A) per device and global profile and B) proc and sysfs interface
usage.

Signed-off-by: Sebastian Ott <sebott@linux.vnet.ibm.com>
Reviewed-by: Stefan Haberland <stefan.haberland@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
drivers/s390/block/dasd.c
drivers/s390/block/dasd_int.h
drivers/s390/block/dasd_proc.c

index a67e8dae73c35bf4cfdf58727b5a562cbafc4c45..be34ef41b7c741ff67e22158aed702580cb2877c 100644 (file)
@@ -674,10 +674,7 @@ EXPORT_SYMBOL(dasd_enable_device);
 unsigned int dasd_global_profile_level = DASD_PROFILE_OFF;
 
 #ifdef CONFIG_DASD_PROFILE
-static struct dasd_profile_info dasd_global_profile_data;
 struct dasd_profile dasd_global_profile = {
-       .dentry = NULL,
-       .data = &dasd_global_profile_data,
        .lock = __SPIN_LOCK_UNLOCKED(dasd_global_profile.lock),
 };
 static struct dentry *dasd_debugfs_global_entry;
@@ -701,7 +698,7 @@ static void dasd_profile_start(struct dasd_block *block,
                                break;
 
        spin_lock(&dasd_global_profile.lock);
-       if (dasd_global_profile_level) {
+       if (dasd_global_profile.data) {
                dasd_global_profile.data->dasd_io_nr_req[counter]++;
                if (rq_data_dir(req) == READ)
                        dasd_global_profile.data->dasd_read_nr_req[counter]++;
@@ -832,7 +829,7 @@ static void dasd_profile_end(struct dasd_block *block,
        dasd_profile_counter(endtime, endtime_ind);
 
        spin_lock(&dasd_global_profile.lock);
-       if (dasd_global_profile_level) {
+       if (dasd_global_profile.data) {
                dasd_profile_end_add_data(dasd_global_profile.data,
                                          cqr->startdev != block->base,
                                          cqr->cpmode == 1,
@@ -884,11 +881,6 @@ void dasd_profile_reset(struct dasd_profile *profile)
        spin_unlock_bh(&profile->lock);
 }
 
-void dasd_global_profile_reset(void)
-{
-       dasd_profile_reset(&dasd_global_profile);
-}
-
 int dasd_profile_on(struct dasd_profile *profile)
 {
        struct dasd_profile_info *data;
@@ -956,12 +948,20 @@ static ssize_t dasd_stats_write(struct file *file,
                dasd_profile_reset(prof);
        } else if (strncmp(str, "on", 2) == 0) {
                rc = dasd_profile_on(prof);
-               if (!rc)
-                       rc = user_len;
+               if (rc)
+                       goto out;
+               rc = user_len;
+               if (prof == &dasd_global_profile) {
+                       dasd_profile_reset(prof);
+                       dasd_global_profile_level = DASD_PROFILE_GLOBAL_ONLY;
+               }
        } else if (strncmp(str, "off", 3) == 0) {
+               if (prof == &dasd_global_profile)
+                       dasd_global_profile_level = DASD_PROFILE_OFF;
                dasd_profile_off(prof);
        } else
                rc = -EINVAL;
+out:
        vfree(buffer);
        return rc;
 }
@@ -1051,59 +1051,6 @@ static const struct file_operations dasd_stats_raw_fops = {
        .write          = dasd_stats_write,
 };
 
-static ssize_t dasd_stats_global_write(struct file *file,
-                                      const char __user *user_buf,
-                                      size_t user_len, loff_t *pos)
-{
-       char *buffer, *str;
-       ssize_t rc;
-
-       if (user_len > 65536)
-               user_len = 65536;
-       buffer = dasd_get_user_string(user_buf, user_len);
-       if (IS_ERR(buffer))
-               return PTR_ERR(buffer);
-       str = skip_spaces(buffer);
-       rc = user_len;
-       if (strncmp(str, "reset", 5) == 0) {
-               dasd_global_profile_reset();
-       } else if (strncmp(str, "on", 2) == 0) {
-               dasd_global_profile_reset();
-               dasd_global_profile_level = DASD_PROFILE_GLOBAL_ONLY;
-       } else if (strncmp(str, "off", 3) == 0) {
-               dasd_global_profile_level = DASD_PROFILE_OFF;
-       } else
-               rc = -EINVAL;
-       vfree(buffer);
-       return rc;
-}
-
-static int dasd_stats_global_show(struct seq_file *m, void *v)
-{
-       if (!dasd_global_profile_level) {
-               seq_puts(m, "disabled\n");
-               return 0;
-       }
-       spin_lock_bh(&dasd_global_profile.lock);
-       dasd_stats_seq_print(m, dasd_global_profile.data);
-       spin_unlock_bh(&dasd_global_profile.lock);
-       return 0;
-}
-
-static int dasd_stats_global_open(struct inode *inode, struct file *file)
-{
-       return single_open(file, dasd_stats_global_show, NULL);
-}
-
-static const struct file_operations dasd_stats_global_fops = {
-       .owner          = THIS_MODULE,
-       .open           = dasd_stats_global_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-       .write          = dasd_stats_global_write,
-};
-
 static void dasd_profile_init(struct dasd_profile *profile,
                              struct dentry *base_dentry)
 {
@@ -1132,19 +1079,16 @@ static void dasd_profile_exit(struct dasd_profile *profile)
 static void dasd_statistics_removeroot(void)
 {
        dasd_global_profile_level = DASD_PROFILE_OFF;
-       debugfs_remove(dasd_global_profile.dentry);
-       dasd_global_profile.dentry = NULL;
+       dasd_profile_exit(&dasd_global_profile);
        debugfs_remove(dasd_debugfs_global_entry);
        debugfs_remove(dasd_debugfs_root_entry);
 }
 
 static void dasd_statistics_createroot(void)
 {
-       umode_t mode;
        struct dentry *pde;
 
        dasd_debugfs_root_entry = NULL;
-       dasd_debugfs_global_entry = NULL;
        pde = debugfs_create_dir("dasd", NULL);
        if (!pde || IS_ERR(pde))
                goto error;
@@ -1153,13 +1097,7 @@ static void dasd_statistics_createroot(void)
        if (!pde || IS_ERR(pde))
                goto error;
        dasd_debugfs_global_entry = pde;
-
-       mode = (S_IRUSR | S_IWUSR | S_IFREG);
-       pde = debugfs_create_file("statistics", mode, dasd_debugfs_global_entry,
-                                 NULL, &dasd_stats_global_fops);
-       if (!pde || IS_ERR(pde))
-               goto error;
-       dasd_global_profile.dentry = pde;
+       dasd_profile_init(&dasd_global_profile, dasd_debugfs_global_entry);
        return;
 
 error:
index 91731fa05604ad0908c5dd1cc04cfb933d88f975..227e3dea3155268e7d060b07937bb7ac6d340732 100644 (file)
@@ -728,7 +728,6 @@ int dasd_device_is_ro(struct dasd_device *);
 void dasd_profile_reset(struct dasd_profile *);
 int dasd_profile_on(struct dasd_profile *);
 void dasd_profile_off(struct dasd_profile *);
-void dasd_global_profile_reset(void);
 char *dasd_get_user_string(const char __user *, size_t);
 
 /* externals in dasd_devmap.c */
index 76410084c48f4bac407dc947c207dba8dc67e282..aa7bb2d1da81154940b7755c69f6744fb710cb15 100644 (file)
@@ -212,15 +212,15 @@ static int dasd_stats_proc_show(struct seq_file *m, void *v)
        struct dasd_profile_info *prof;
        int factor;
 
-       /* check for active profiling */
-       if (!dasd_global_profile_level) {
+       spin_lock_bh(&dasd_global_profile.lock);
+       prof = dasd_global_profile.data;
+       if (!prof) {
+               spin_unlock_bh(&dasd_global_profile.lock);
                seq_printf(m, "Statistics are off - they might be "
                                    "switched on using 'echo set on > "
                                    "/proc/dasd/statistics'\n");
                return 0;
        }
-       spin_lock_bh(&dasd_global_profile.lock);
-       prof = dasd_global_profile.data;
 
        /* prevent counter 'overflow' on output */
        for (factor = 1; (prof->dasd_io_reqs / factor) > 9999999;
@@ -293,14 +293,19 @@ static ssize_t dasd_stats_proc_write(struct file *file,
                                dasd_stats_all_block_off();
                                goto out_error;
                        }
-                       dasd_global_profile_reset();
+                       rc = dasd_profile_on(&dasd_global_profile);
+                       if (rc) {
+                               dasd_stats_all_block_off();
+                               goto out_error;
+                       }
+                       dasd_profile_reset(&dasd_global_profile);
                        dasd_global_profile_level = DASD_PROFILE_ON;
                        pr_info("The statistics feature has been switched "
                                "on\n");
                } else if (strcmp(str, "off") == 0) {
-                       /* switch off and reset statistics profiling */
+                       /* switch off statistics profiling */
                        dasd_global_profile_level = DASD_PROFILE_OFF;
-                       dasd_global_profile_reset();
+                       dasd_profile_off(&dasd_global_profile);
                        dasd_stats_all_block_off();
                        pr_info("The statistics feature has been switched "
                                "off\n");
@@ -308,7 +313,7 @@ static ssize_t dasd_stats_proc_write(struct file *file,
                        goto out_parse_error;
        } else if (strncmp(str, "reset", 5) == 0) {
                /* reset the statistics */
-               dasd_global_profile_reset();
+               dasd_profile_reset(&dasd_global_profile);
                dasd_stats_all_block_reset();
                pr_info("The statistics have been reset\n");
        } else