summary refs log tree commit diff
path: root/drivers
diff options
context:
space:
mode:
authorSebastian Ott <sebott@linux.vnet.ibm.com>2015-01-28 19:06:29 +0100
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2015-01-29 09:19:29 +0100
commit6765cc2ac60f124ffffd0232e095c5ec6eb70d57 (patch)
treea52bba262de0b68d9fc261e5d51471f0932d6b88 /drivers
parent8ea55c95c372a7a51fa50cb7c75240bfbe8bd337 (diff)
downloadlinux-6765cc2ac60f124ffffd0232e095c5ec6eb70d57.tar.gz
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>
Diffstat (limited to 'drivers')
-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);
 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:
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 *);
 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 */
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)
 	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