aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390
diff options
context:
space:
mode:
authorSebastian Ott <sebott@linux.vnet.ibm.com>2015-01-28 12:44:17 -0500
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2015-01-29 03:19:27 -0500
commit8ea55c95c372a7a51fa50cb7c75240bfbe8bd337 (patch)
treea7a496ce7f0f0ae9a417d50acb44fb9fe1229ff9 /drivers/s390
parente6d60b368b45b9be3aa068f8e5fa98c3487c9d4e (diff)
s390/dasd: add locking for global_profile access
Access to DASDs global statistics is done without locking which can lead to inconsistent data. Add locking to fix this. Also move the relevant structs in a global dasd_profile struct. 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/s390')
-rw-r--r--drivers/s390/block/dasd.c32
-rw-r--r--drivers/s390/block/dasd_int.h2
-rw-r--r--drivers/s390/block/dasd_proc.c4
3 files changed, 24 insertions, 14 deletions
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index 4abf11965484..a67e8dae73c3 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -674,8 +674,12 @@ 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
677struct dasd_profile_info dasd_global_profile_data; 677static struct dasd_profile_info dasd_global_profile_data;
678static struct dentry *dasd_global_profile_dentry; 678struct dasd_profile dasd_global_profile = {
679 .dentry = NULL,
680 .data = &dasd_global_profile_data,
681 .lock = __SPIN_LOCK_UNLOCKED(dasd_global_profile.lock),
682};
679static struct dentry *dasd_debugfs_global_entry; 683static struct dentry *dasd_debugfs_global_entry;
680 684
681/* 685/*
@@ -696,11 +700,13 @@ static void dasd_profile_start(struct dasd_block *block,
696 if (++counter >= 31) 700 if (++counter >= 31)
697 break; 701 break;
698 702
703 spin_lock(&dasd_global_profile.lock);
699 if (dasd_global_profile_level) { 704 if (dasd_global_profile_level) {
700 dasd_global_profile_data.dasd_io_nr_req[counter]++; 705 dasd_global_profile.data->dasd_io_nr_req[counter]++;
701 if (rq_data_dir(req) == READ) 706 if (rq_data_dir(req) == READ)
702 dasd_global_profile_data.dasd_read_nr_req[counter]++; 707 dasd_global_profile.data->dasd_read_nr_req[counter]++;
703 } 708 }
709 spin_unlock(&dasd_global_profile.lock);
704 710
705 spin_lock(&block->profile.lock); 711 spin_lock(&block->profile.lock);
706 if (block->profile.data) { 712 if (block->profile.data) {
@@ -825,8 +831,9 @@ static void dasd_profile_end(struct dasd_block *block,
825 dasd_profile_counter(irqtime / sectors, irqtimeps_ind); 831 dasd_profile_counter(irqtime / sectors, irqtimeps_ind);
826 dasd_profile_counter(endtime, endtime_ind); 832 dasd_profile_counter(endtime, endtime_ind);
827 833
834 spin_lock(&dasd_global_profile.lock);
828 if (dasd_global_profile_level) { 835 if (dasd_global_profile_level) {
829 dasd_profile_end_add_data(&dasd_global_profile_data, 836 dasd_profile_end_add_data(dasd_global_profile.data,
830 cqr->startdev != block->base, 837 cqr->startdev != block->base,
831 cqr->cpmode == 1, 838 cqr->cpmode == 1,
832 rq_data_dir(req) == READ, 839 rq_data_dir(req) == READ,
@@ -835,6 +842,7 @@ static void dasd_profile_end(struct dasd_block *block,
835 irqtime_ind, irqtimeps_ind, 842 irqtime_ind, irqtimeps_ind,
836 endtime_ind); 843 endtime_ind);
837 } 844 }
845 spin_unlock(&dasd_global_profile.lock);
838 846
839 spin_lock(&block->profile.lock); 847 spin_lock(&block->profile.lock);
840 if (block->profile.data) 848 if (block->profile.data)
@@ -878,8 +886,7 @@ void dasd_profile_reset(struct dasd_profile *profile)
878 886
879void dasd_global_profile_reset(void) 887void dasd_global_profile_reset(void)
880{ 888{
881 memset(&dasd_global_profile_data, 0, sizeof(dasd_global_profile_data)); 889 dasd_profile_reset(&dasd_global_profile);
882 getnstimeofday(&dasd_global_profile_data.starttod);
883} 890}
884 891
885int dasd_profile_on(struct dasd_profile *profile) 892int dasd_profile_on(struct dasd_profile *profile)
@@ -1077,7 +1084,9 @@ static int dasd_stats_global_show(struct seq_file *m, void *v)
1077 seq_puts(m, "disabled\n"); 1084 seq_puts(m, "disabled\n");
1078 return 0; 1085 return 0;
1079 } 1086 }
1080 dasd_stats_seq_print(m, &dasd_global_profile_data); 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);
1081 return 0; 1090 return 0;
1082} 1091}
1083 1092
@@ -1123,8 +1132,8 @@ static void dasd_profile_exit(struct dasd_profile *profile)
1123static void dasd_statistics_removeroot(void) 1132static void dasd_statistics_removeroot(void)
1124{ 1133{
1125 dasd_global_profile_level = DASD_PROFILE_OFF; 1134 dasd_global_profile_level = DASD_PROFILE_OFF;
1126 debugfs_remove(dasd_global_profile_dentry); 1135 debugfs_remove(dasd_global_profile.dentry);
1127 dasd_global_profile_dentry = NULL; 1136 dasd_global_profile.dentry = NULL;
1128 debugfs_remove(dasd_debugfs_global_entry); 1137 debugfs_remove(dasd_debugfs_global_entry);
1129 debugfs_remove(dasd_debugfs_root_entry); 1138 debugfs_remove(dasd_debugfs_root_entry);
1130} 1139}
@@ -1136,7 +1145,6 @@ static void dasd_statistics_createroot(void)
1136 1145
1137 dasd_debugfs_root_entry = NULL; 1146 dasd_debugfs_root_entry = NULL;
1138 dasd_debugfs_global_entry = NULL; 1147 dasd_debugfs_global_entry = NULL;
1139 dasd_global_profile_dentry = NULL;
1140 pde = debugfs_create_dir("dasd", NULL); 1148 pde = debugfs_create_dir("dasd", NULL);
1141 if (!pde || IS_ERR(pde)) 1149 if (!pde || IS_ERR(pde))
1142 goto error; 1150 goto error;
@@ -1151,7 +1159,7 @@ static void dasd_statistics_createroot(void)
1151 NULL, &dasd_stats_global_fops); 1159 NULL, &dasd_stats_global_fops);
1152 if (!pde || IS_ERR(pde)) 1160 if (!pde || IS_ERR(pde))
1153 goto error; 1161 goto error;
1154 dasd_global_profile_dentry = pde; 1162 dasd_global_profile.dentry = pde;
1155 return; 1163 return;
1156 1164
1157error: 1165error:
diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h
index 8b5d4100abf7..91731fa05604 100644
--- a/drivers/s390/block/dasd_int.h
+++ b/drivers/s390/block/dasd_int.h
@@ -651,7 +651,7 @@ dasd_check_blocksize(int bsize)
651#define DASD_PROFILE_GLOBAL_ONLY 2 651#define DASD_PROFILE_GLOBAL_ONLY 2
652 652
653extern debug_info_t *dasd_debug_area; 653extern debug_info_t *dasd_debug_area;
654extern struct dasd_profile_info dasd_global_profile_data; 654extern struct dasd_profile dasd_global_profile;
655extern unsigned int dasd_global_profile_level; 655extern unsigned int dasd_global_profile_level;
656extern const struct block_device_operations dasd_device_operations; 656extern const struct block_device_operations dasd_device_operations;
657 657
diff --git a/drivers/s390/block/dasd_proc.c b/drivers/s390/block/dasd_proc.c
index 78ac905a5b7f..76410084c48f 100644
--- a/drivers/s390/block/dasd_proc.c
+++ b/drivers/s390/block/dasd_proc.c
@@ -219,7 +219,8 @@ static int dasd_stats_proc_show(struct seq_file *m, void *v)
219 "/proc/dasd/statistics'\n"); 219 "/proc/dasd/statistics'\n");
220 return 0; 220 return 0;
221 } 221 }
222 prof = &dasd_global_profile_data; 222 spin_lock_bh(&dasd_global_profile.lock);
223 prof = dasd_global_profile.data;
223 224
224 /* prevent counter 'overflow' on output */ 225 /* prevent counter 'overflow' on output */
225 for (factor = 1; (prof->dasd_io_reqs / factor) > 9999999; 226 for (factor = 1; (prof->dasd_io_reqs / factor) > 9999999;
@@ -255,6 +256,7 @@ static int dasd_stats_proc_show(struct seq_file *m, void *v)
255 dasd_statistics_array(m, prof->dasd_io_time3, factor); 256 dasd_statistics_array(m, prof->dasd_io_time3, factor);
256 seq_printf(m, "# of req in chanq at enqueuing (1..32) \n"); 257 seq_printf(m, "# of req in chanq at enqueuing (1..32) \n");
257 dasd_statistics_array(m, prof->dasd_io_nr_req, factor); 258 dasd_statistics_array(m, prof->dasd_io_nr_req, factor);
259 spin_unlock_bh(&dasd_global_profile.lock);
258#else 260#else
259 seq_printf(m, "Statistics are not activated in this kernel\n"); 261 seq_printf(m, "Statistics are not activated in this kernel\n");
260#endif 262#endif