diff options
author | Sebastian Ott <sebott@linux.vnet.ibm.com> | 2015-01-28 13:06:29 -0500 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2015-01-29 03:19:29 -0500 |
commit | 6765cc2ac60f124ffffd0232e095c5ec6eb70d57 (patch) | |
tree | a52bba262de0b68d9fc261e5d51471f0932d6b88 | |
parent | 8ea55c95c372a7a51fa50cb7c75240bfbe8bd337 (diff) |
s390/dasd: cleanup profiling
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>
-rw-r--r-- | drivers/s390/block/dasd.c | 90 | ||||
-rw-r--r-- | drivers/s390/block/dasd_int.h | 1 | ||||
-rw-r--r-- | drivers/s390/block/dasd_proc.c | 21 |
3 files changed, 27 insertions, 85 deletions
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index a67e8dae73c3..be34ef41b7c7 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c | |||
@@ -674,10 +674,7 @@ EXPORT_SYMBOL(dasd_enable_device); | |||
674 | unsigned int dasd_global_profile_level = DASD_PROFILE_OFF; | 674 | unsigned int dasd_global_profile_level = DASD_PROFILE_OFF; |
675 | 675 | ||
676 | #ifdef CONFIG_DASD_PROFILE | 676 | #ifdef CONFIG_DASD_PROFILE |
677 | static struct dasd_profile_info dasd_global_profile_data; | ||
678 | struct dasd_profile dasd_global_profile = { | 677 | struct dasd_profile dasd_global_profile = { |
679 | .dentry = NULL, | ||
680 | .data = &dasd_global_profile_data, | ||
681 | .lock = __SPIN_LOCK_UNLOCKED(dasd_global_profile.lock), | 678 | .lock = __SPIN_LOCK_UNLOCKED(dasd_global_profile.lock), |
682 | }; | 679 | }; |
683 | static struct dentry *dasd_debugfs_global_entry; | 680 | static struct dentry *dasd_debugfs_global_entry; |
@@ -701,7 +698,7 @@ static void dasd_profile_start(struct dasd_block *block, | |||
701 | break; | 698 | break; |
702 | 699 | ||
703 | spin_lock(&dasd_global_profile.lock); | 700 | spin_lock(&dasd_global_profile.lock); |
704 | if (dasd_global_profile_level) { | 701 | if (dasd_global_profile.data) { |
705 | dasd_global_profile.data->dasd_io_nr_req[counter]++; | 702 | dasd_global_profile.data->dasd_io_nr_req[counter]++; |
706 | if (rq_data_dir(req) == READ) | 703 | if (rq_data_dir(req) == READ) |
707 | dasd_global_profile.data->dasd_read_nr_req[counter]++; | 704 | dasd_global_profile.data->dasd_read_nr_req[counter]++; |
@@ -832,7 +829,7 @@ static void dasd_profile_end(struct dasd_block *block, | |||
832 | dasd_profile_counter(endtime, endtime_ind); | 829 | dasd_profile_counter(endtime, endtime_ind); |
833 | 830 | ||
834 | spin_lock(&dasd_global_profile.lock); | 831 | spin_lock(&dasd_global_profile.lock); |
835 | if (dasd_global_profile_level) { | 832 | if (dasd_global_profile.data) { |
836 | dasd_profile_end_add_data(dasd_global_profile.data, | 833 | dasd_profile_end_add_data(dasd_global_profile.data, |
837 | cqr->startdev != block->base, | 834 | cqr->startdev != block->base, |
838 | cqr->cpmode == 1, | 835 | cqr->cpmode == 1, |
@@ -884,11 +881,6 @@ void dasd_profile_reset(struct dasd_profile *profile) | |||
884 | spin_unlock_bh(&profile->lock); | 881 | spin_unlock_bh(&profile->lock); |
885 | } | 882 | } |
886 | 883 | ||
887 | void dasd_global_profile_reset(void) | ||
888 | { | ||
889 | dasd_profile_reset(&dasd_global_profile); | ||
890 | } | ||
891 | |||
892 | int dasd_profile_on(struct dasd_profile *profile) | 884 | int dasd_profile_on(struct dasd_profile *profile) |
893 | { | 885 | { |
894 | struct dasd_profile_info *data; | 886 | struct dasd_profile_info *data; |
@@ -956,12 +948,20 @@ static ssize_t dasd_stats_write(struct file *file, | |||
956 | dasd_profile_reset(prof); | 948 | dasd_profile_reset(prof); |
957 | } else if (strncmp(str, "on", 2) == 0) { | 949 | } else if (strncmp(str, "on", 2) == 0) { |
958 | rc = dasd_profile_on(prof); | 950 | rc = dasd_profile_on(prof); |
959 | if (!rc) | 951 | if (rc) |
960 | rc = user_len; | 952 | goto out; |
953 | rc = user_len; | ||
954 | if (prof == &dasd_global_profile) { | ||
955 | dasd_profile_reset(prof); | ||
956 | dasd_global_profile_level = DASD_PROFILE_GLOBAL_ONLY; | ||
957 | } | ||
961 | } else if (strncmp(str, "off", 3) == 0) { | 958 | } else if (strncmp(str, "off", 3) == 0) { |
959 | if (prof == &dasd_global_profile) | ||
960 | dasd_global_profile_level = DASD_PROFILE_OFF; | ||
962 | dasd_profile_off(prof); | 961 | dasd_profile_off(prof); |
963 | } else | 962 | } else |
964 | rc = -EINVAL; | 963 | rc = -EINVAL; |
964 | out: | ||
965 | vfree(buffer); | 965 | vfree(buffer); |
966 | return rc; | 966 | return rc; |
967 | } | 967 | } |
@@ -1051,59 +1051,6 @@ static const struct file_operations dasd_stats_raw_fops = { | |||
1051 | .write = dasd_stats_write, | 1051 | .write = dasd_stats_write, |
1052 | }; | 1052 | }; |
1053 | 1053 | ||
1054 | static ssize_t dasd_stats_global_write(struct file *file, | ||
1055 | const char __user *user_buf, | ||
1056 | size_t user_len, loff_t *pos) | ||
1057 | { | ||
1058 | char *buffer, *str; | ||
1059 | ssize_t rc; | ||
1060 | |||
1061 | if (user_len > 65536) | ||
1062 | user_len = 65536; | ||
1063 | buffer = dasd_get_user_string(user_buf, user_len); | ||
1064 | if (IS_ERR(buffer)) | ||
1065 | return PTR_ERR(buffer); | ||
1066 | str = skip_spaces(buffer); | ||
1067 | rc = user_len; | ||
1068 | if (strncmp(str, "reset", 5) == 0) { | ||
1069 | dasd_global_profile_reset(); | ||
1070 | } else if (strncmp(str, "on", 2) == 0) { | ||
1071 | dasd_global_profile_reset(); | ||
1072 | dasd_global_profile_level = DASD_PROFILE_GLOBAL_ONLY; | ||
1073 | } else if (strncmp(str, "off", 3) == 0) { | ||
1074 | dasd_global_profile_level = DASD_PROFILE_OFF; | ||
1075 | } else | ||
1076 | rc = -EINVAL; | ||
1077 | vfree(buffer); | ||
1078 | return rc; | ||
1079 | } | ||
1080 | |||
1081 | static int dasd_stats_global_show(struct seq_file *m, void *v) | ||
1082 | { | ||
1083 | if (!dasd_global_profile_level) { | ||
1084 | seq_puts(m, "disabled\n"); | ||
1085 | return 0; | ||
1086 | } | ||
1087 | spin_lock_bh(&dasd_global_profile.lock); | ||
1088 | dasd_stats_seq_print(m, dasd_global_profile.data); | ||
1089 | spin_unlock_bh(&dasd_global_profile.lock); | ||
1090 | return 0; | ||
1091 | } | ||
1092 | |||
1093 | static int dasd_stats_global_open(struct inode *inode, struct file *file) | ||
1094 | { | ||
1095 | return single_open(file, dasd_stats_global_show, NULL); | ||
1096 | } | ||
1097 | |||
1098 | static const struct file_operations dasd_stats_global_fops = { | ||
1099 | .owner = THIS_MODULE, | ||
1100 | .open = dasd_stats_global_open, | ||
1101 | .read = seq_read, | ||
1102 | .llseek = seq_lseek, | ||
1103 | .release = single_release, | ||
1104 | .write = dasd_stats_global_write, | ||
1105 | }; | ||
1106 | |||
1107 | static void dasd_profile_init(struct dasd_profile *profile, | 1054 | static void dasd_profile_init(struct dasd_profile *profile, |
1108 | struct dentry *base_dentry) | 1055 | struct dentry *base_dentry) |
1109 | { | 1056 | { |
@@ -1132,19 +1079,16 @@ static void dasd_profile_exit(struct dasd_profile *profile) | |||
1132 | static void dasd_statistics_removeroot(void) | 1079 | static void dasd_statistics_removeroot(void) |
1133 | { | 1080 | { |
1134 | dasd_global_profile_level = DASD_PROFILE_OFF; | 1081 | dasd_global_profile_level = DASD_PROFILE_OFF; |
1135 | debugfs_remove(dasd_global_profile.dentry); | 1082 | dasd_profile_exit(&dasd_global_profile); |
1136 | dasd_global_profile.dentry = NULL; | ||
1137 | debugfs_remove(dasd_debugfs_global_entry); | 1083 | debugfs_remove(dasd_debugfs_global_entry); |
1138 | debugfs_remove(dasd_debugfs_root_entry); | 1084 | debugfs_remove(dasd_debugfs_root_entry); |
1139 | } | 1085 | } |
1140 | 1086 | ||
1141 | static void dasd_statistics_createroot(void) | 1087 | static void dasd_statistics_createroot(void) |
1142 | { | 1088 | { |
1143 | umode_t mode; | ||
1144 | struct dentry *pde; | 1089 | struct dentry *pde; |
1145 | 1090 | ||
1146 | dasd_debugfs_root_entry = NULL; | 1091 | dasd_debugfs_root_entry = NULL; |
1147 | dasd_debugfs_global_entry = NULL; | ||
1148 | pde = debugfs_create_dir("dasd", NULL); | 1092 | pde = debugfs_create_dir("dasd", NULL); |
1149 | if (!pde || IS_ERR(pde)) | 1093 | if (!pde || IS_ERR(pde)) |
1150 | goto error; | 1094 | goto error; |
@@ -1153,13 +1097,7 @@ static void dasd_statistics_createroot(void) | |||
1153 | if (!pde || IS_ERR(pde)) | 1097 | if (!pde || IS_ERR(pde)) |
1154 | goto error; | 1098 | goto error; |
1155 | dasd_debugfs_global_entry = pde; | 1099 | dasd_debugfs_global_entry = pde; |
1156 | 1100 | dasd_profile_init(&dasd_global_profile, dasd_debugfs_global_entry); | |
1157 | mode = (S_IRUSR | S_IWUSR | S_IFREG); | ||
1158 | pde = debugfs_create_file("statistics", mode, dasd_debugfs_global_entry, | ||
1159 | NULL, &dasd_stats_global_fops); | ||
1160 | if (!pde || IS_ERR(pde)) | ||
1161 | goto error; | ||
1162 | dasd_global_profile.dentry = pde; | ||
1163 | return; | 1101 | return; |
1164 | 1102 | ||
1165 | error: | 1103 | error: |
diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h index 91731fa05604..227e3dea3155 100644 --- a/drivers/s390/block/dasd_int.h +++ b/drivers/s390/block/dasd_int.h | |||
@@ -728,7 +728,6 @@ int dasd_device_is_ro(struct dasd_device *); | |||
728 | void dasd_profile_reset(struct dasd_profile *); | 728 | void dasd_profile_reset(struct dasd_profile *); |
729 | int dasd_profile_on(struct dasd_profile *); | 729 | int dasd_profile_on(struct dasd_profile *); |
730 | void dasd_profile_off(struct dasd_profile *); | 730 | void dasd_profile_off(struct dasd_profile *); |
731 | void dasd_global_profile_reset(void); | ||
732 | char *dasd_get_user_string(const char __user *, size_t); | 731 | char *dasd_get_user_string(const char __user *, size_t); |
733 | 732 | ||
734 | /* externals in dasd_devmap.c */ | 733 | /* externals in dasd_devmap.c */ |
diff --git a/drivers/s390/block/dasd_proc.c b/drivers/s390/block/dasd_proc.c index 76410084c48f..aa7bb2d1da81 100644 --- a/drivers/s390/block/dasd_proc.c +++ b/drivers/s390/block/dasd_proc.c | |||
@@ -212,15 +212,15 @@ static int dasd_stats_proc_show(struct seq_file *m, void *v) | |||
212 | struct dasd_profile_info *prof; | 212 | struct dasd_profile_info *prof; |
213 | int factor; | 213 | int factor; |
214 | 214 | ||
215 | /* check for active profiling */ | 215 | spin_lock_bh(&dasd_global_profile.lock); |
216 | if (!dasd_global_profile_level) { | 216 | prof = dasd_global_profile.data; |
217 | if (!prof) { | ||
218 | spin_unlock_bh(&dasd_global_profile.lock); | ||
217 | seq_printf(m, "Statistics are off - they might be " | 219 | seq_printf(m, "Statistics are off - they might be " |
218 | "switched on using 'echo set on > " | 220 | "switched on using 'echo set on > " |
219 | "/proc/dasd/statistics'\n"); | 221 | "/proc/dasd/statistics'\n"); |
220 | return 0; | 222 | return 0; |
221 | } | 223 | } |
222 | spin_lock_bh(&dasd_global_profile.lock); | ||
223 | prof = dasd_global_profile.data; | ||
224 | 224 | ||
225 | /* prevent counter 'overflow' on output */ | 225 | /* prevent counter 'overflow' on output */ |
226 | for (factor = 1; (prof->dasd_io_reqs / factor) > 9999999; | 226 | for (factor = 1; (prof->dasd_io_reqs / factor) > 9999999; |
@@ -293,14 +293,19 @@ static ssize_t dasd_stats_proc_write(struct file *file, | |||
293 | dasd_stats_all_block_off(); | 293 | dasd_stats_all_block_off(); |
294 | goto out_error; | 294 | goto out_error; |
295 | } | 295 | } |
296 | dasd_global_profile_reset(); | 296 | rc = dasd_profile_on(&dasd_global_profile); |
297 | if (rc) { | ||
298 | dasd_stats_all_block_off(); | ||
299 | goto out_error; | ||
300 | } | ||
301 | dasd_profile_reset(&dasd_global_profile); | ||
297 | dasd_global_profile_level = DASD_PROFILE_ON; | 302 | dasd_global_profile_level = DASD_PROFILE_ON; |
298 | pr_info("The statistics feature has been switched " | 303 | pr_info("The statistics feature has been switched " |
299 | "on\n"); | 304 | "on\n"); |
300 | } else if (strcmp(str, "off") == 0) { | 305 | } else if (strcmp(str, "off") == 0) { |
301 | /* switch off and reset statistics profiling */ | 306 | /* switch off statistics profiling */ |
302 | dasd_global_profile_level = DASD_PROFILE_OFF; | 307 | dasd_global_profile_level = DASD_PROFILE_OFF; |
303 | dasd_global_profile_reset(); | 308 | dasd_profile_off(&dasd_global_profile); |
304 | dasd_stats_all_block_off(); | 309 | dasd_stats_all_block_off(); |
305 | pr_info("The statistics feature has been switched " | 310 | pr_info("The statistics feature has been switched " |
306 | "off\n"); | 311 | "off\n"); |
@@ -308,7 +313,7 @@ static ssize_t dasd_stats_proc_write(struct file *file, | |||
308 | goto out_parse_error; | 313 | goto out_parse_error; |
309 | } else if (strncmp(str, "reset", 5) == 0) { | 314 | } else if (strncmp(str, "reset", 5) == 0) { |
310 | /* reset the statistics */ | 315 | /* reset the statistics */ |
311 | dasd_global_profile_reset(); | 316 | dasd_profile_reset(&dasd_global_profile); |
312 | dasd_stats_all_block_reset(); | 317 | dasd_stats_all_block_reset(); |
313 | pr_info("The statistics have been reset\n"); | 318 | pr_info("The statistics have been reset\n"); |
314 | } else | 319 | } else |