2
0
mirror of https://github.com/edk2-porting/linux-next.git synced 2025-01-23 22:25:40 +08:00

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>
This commit is contained in:
Sebastian Ott 2015-01-28 19:06:29 +01:00 committed by Martin Schwidefsky
parent 8ea55c95c3
commit 6765cc2ac6
3 changed files with 27 additions and 85 deletions

View File

@ -674,10 +674,7 @@ EXPORT_SYMBOL(dasd_enable_device);
unsigned int dasd_global_profile_level = DASD_PROFILE_OFF; unsigned int dasd_global_profile_level = DASD_PROFILE_OFF;
#ifdef CONFIG_DASD_PROFILE #ifdef CONFIG_DASD_PROFILE
static struct dasd_profile_info dasd_global_profile_data;
struct dasd_profile dasd_global_profile = { struct dasd_profile dasd_global_profile = {
.dentry = NULL,
.data = &dasd_global_profile_data,
.lock = __SPIN_LOCK_UNLOCKED(dasd_global_profile.lock), .lock = __SPIN_LOCK_UNLOCKED(dasd_global_profile.lock),
}; };
static struct dentry *dasd_debugfs_global_entry; static struct dentry *dasd_debugfs_global_entry;
@ -701,7 +698,7 @@ static void dasd_profile_start(struct dasd_block *block,
break; break;
spin_lock(&dasd_global_profile.lock); 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]++; dasd_global_profile.data->dasd_io_nr_req[counter]++;
if (rq_data_dir(req) == READ) if (rq_data_dir(req) == READ)
dasd_global_profile.data->dasd_read_nr_req[counter]++; 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); dasd_profile_counter(endtime, endtime_ind);
spin_lock(&dasd_global_profile.lock); 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, dasd_profile_end_add_data(dasd_global_profile.data,
cqr->startdev != block->base, cqr->startdev != block->base,
cqr->cpmode == 1, cqr->cpmode == 1,
@ -884,11 +881,6 @@ void dasd_profile_reset(struct dasd_profile *profile)
spin_unlock_bh(&profile->lock); 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) int dasd_profile_on(struct dasd_profile *profile)
{ {
struct dasd_profile_info *data; struct dasd_profile_info *data;
@ -956,12 +948,20 @@ static ssize_t dasd_stats_write(struct file *file,
dasd_profile_reset(prof); dasd_profile_reset(prof);
} else if (strncmp(str, "on", 2) == 0) { } else if (strncmp(str, "on", 2) == 0) {
rc = dasd_profile_on(prof); rc = dasd_profile_on(prof);
if (!rc) if (rc)
rc = user_len; 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) { } else if (strncmp(str, "off", 3) == 0) {
if (prof == &dasd_global_profile)
dasd_global_profile_level = DASD_PROFILE_OFF;
dasd_profile_off(prof); dasd_profile_off(prof);
} else } else
rc = -EINVAL; rc = -EINVAL;
out:
vfree(buffer); vfree(buffer);
return rc; return rc;
} }
@ -1051,59 +1051,6 @@ static const struct file_operations dasd_stats_raw_fops = {
.write = dasd_stats_write, .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, static void dasd_profile_init(struct dasd_profile *profile,
struct dentry *base_dentry) struct dentry *base_dentry)
{ {
@ -1132,19 +1079,16 @@ static void dasd_profile_exit(struct dasd_profile *profile)
static void dasd_statistics_removeroot(void) static void dasd_statistics_removeroot(void)
{ {
dasd_global_profile_level = DASD_PROFILE_OFF; dasd_global_profile_level = DASD_PROFILE_OFF;
debugfs_remove(dasd_global_profile.dentry); dasd_profile_exit(&dasd_global_profile);
dasd_global_profile.dentry = NULL;
debugfs_remove(dasd_debugfs_global_entry); debugfs_remove(dasd_debugfs_global_entry);
debugfs_remove(dasd_debugfs_root_entry); debugfs_remove(dasd_debugfs_root_entry);
} }
static void dasd_statistics_createroot(void) static void dasd_statistics_createroot(void)
{ {
umode_t mode;
struct dentry *pde; struct dentry *pde;
dasd_debugfs_root_entry = NULL; dasd_debugfs_root_entry = NULL;
dasd_debugfs_global_entry = NULL;
pde = debugfs_create_dir("dasd", NULL); pde = debugfs_create_dir("dasd", NULL);
if (!pde || IS_ERR(pde)) if (!pde || IS_ERR(pde))
goto error; goto error;
@ -1153,13 +1097,7 @@ static void dasd_statistics_createroot(void)
if (!pde || IS_ERR(pde)) if (!pde || IS_ERR(pde))
goto error; goto error;
dasd_debugfs_global_entry = pde; dasd_debugfs_global_entry = pde;
dasd_profile_init(&dasd_global_profile, dasd_debugfs_global_entry);
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;
return; return;
error: error:

View File

@ -728,7 +728,6 @@ int dasd_device_is_ro(struct dasd_device *);
void dasd_profile_reset(struct dasd_profile *); void dasd_profile_reset(struct dasd_profile *);
int dasd_profile_on(struct dasd_profile *); int dasd_profile_on(struct dasd_profile *);
void dasd_profile_off(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); char *dasd_get_user_string(const char __user *, size_t);
/* externals in dasd_devmap.c */ /* externals in dasd_devmap.c */

View File

@ -212,15 +212,15 @@ static int dasd_stats_proc_show(struct seq_file *m, void *v)
struct dasd_profile_info *prof; struct dasd_profile_info *prof;
int factor; int factor;
/* check for active profiling */ spin_lock_bh(&dasd_global_profile.lock);
if (!dasd_global_profile_level) { prof = dasd_global_profile.data;
if (!prof) {
spin_unlock_bh(&dasd_global_profile.lock);
seq_printf(m, "Statistics are off - they might be " seq_printf(m, "Statistics are off - they might be "
"switched on using 'echo set on > " "switched on using 'echo set on > "
"/proc/dasd/statistics'\n"); "/proc/dasd/statistics'\n");
return 0; return 0;
} }
spin_lock_bh(&dasd_global_profile.lock);
prof = dasd_global_profile.data;
/* prevent counter 'overflow' on output */ /* prevent counter 'overflow' on output */
for (factor = 1; (prof->dasd_io_reqs / factor) > 9999999; 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(); dasd_stats_all_block_off();
goto out_error; 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; dasd_global_profile_level = DASD_PROFILE_ON;
pr_info("The statistics feature has been switched " pr_info("The statistics feature has been switched "
"on\n"); "on\n");
} else if (strcmp(str, "off") == 0) { } 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_level = DASD_PROFILE_OFF;
dasd_global_profile_reset(); dasd_profile_off(&dasd_global_profile);
dasd_stats_all_block_off(); dasd_stats_all_block_off();
pr_info("The statistics feature has been switched " pr_info("The statistics feature has been switched "
"off\n"); "off\n");
@ -308,7 +313,7 @@ static ssize_t dasd_stats_proc_write(struct file *file,
goto out_parse_error; goto out_parse_error;
} else if (strncmp(str, "reset", 5) == 0) { } else if (strncmp(str, "reset", 5) == 0) {
/* reset the statistics */ /* reset the statistics */
dasd_global_profile_reset(); dasd_profile_reset(&dasd_global_profile);
dasd_stats_all_block_reset(); dasd_stats_all_block_reset();
pr_info("The statistics have been reset\n"); pr_info("The statistics have been reset\n");
} else } else