aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Ott <sebott@linux.vnet.ibm.com>2015-01-28 13:06:29 -0500
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2015-01-29 03:19:29 -0500
commit6765cc2ac60f124ffffd0232e095c5ec6eb70d57 (patch)
treea52bba262de0b68d9fc261e5d51471f0932d6b88
parent8ea55c95c372a7a51fa50cb7c75240bfbe8bd337 (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.c90
-rw-r--r--drivers/s390/block/dasd_int.h1
-rw-r--r--drivers/s390/block/dasd_proc.c21
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);
674unsigned int dasd_global_profile_level = DASD_PROFILE_OFF; 674unsigned int dasd_global_profile_level = DASD_PROFILE_OFF;
675 675
676#ifdef CONFIG_DASD_PROFILE 676#ifdef CONFIG_DASD_PROFILE
677static struct dasd_profile_info dasd_global_profile_data;
678struct dasd_profile dasd_global_profile = { 677struct 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};
683static struct dentry *dasd_debugfs_global_entry; 680static 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
887void dasd_global_profile_reset(void)
888{
889 dasd_profile_reset(&dasd_global_profile);
890}
891
892int dasd_profile_on(struct dasd_profile *profile) 884int 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;
964out:
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
1054static 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
1081static 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
1093static int dasd_stats_global_open(struct inode *inode, struct file *file)
1094{
1095 return single_open(file, dasd_stats_global_show, NULL);
1096}
1097
1098static 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
1107static void dasd_profile_init(struct dasd_profile *profile, 1054static 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)
1132static void dasd_statistics_removeroot(void) 1079static 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
1141static void dasd_statistics_createroot(void) 1087static 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
1165error: 1103error:
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 *);
728void dasd_profile_reset(struct dasd_profile *); 728void dasd_profile_reset(struct dasd_profile *);
729int dasd_profile_on(struct dasd_profile *); 729int dasd_profile_on(struct dasd_profile *);
730void dasd_profile_off(struct dasd_profile *); 730void dasd_profile_off(struct dasd_profile *);
731void dasd_global_profile_reset(void);
732char *dasd_get_user_string(const char __user *, size_t); 731char *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