1 Index: linux-2.6.5-SLES9_SP1_BRANCH_2004111114454891_lustre.1.4.0-phik/drivers/scsi/Kconfig
2 ===================================================================
3 --- linux-2.6.5-SLES9_SP1_BRANCH_2004111114454891_lustre.1.4.0-phik.orig/drivers/scsi/Kconfig 2004-11-11 07:28:52.000000000 -0800
4 +++ linux-2.6.5-SLES9_SP1_BRANCH_2004111114454891_lustre.1.4.0-phik/drivers/scsi/Kconfig 2005-01-06 22:58:42.338770968 -0800
6 In this case, do not compile the driver for your SCSI host adapter
7 (below) as a module either.
10 + bool "Enable SCSI disk I/O stats"
11 + depends on BLK_DEV_SD
14 + This enables SCSI disk I/O stats collection. You must also enable
15 + /proc file system support if you want this feature.
18 tristate "SCSI tape support"
20 Index: linux-2.6.5-SLES9_SP1_BRANCH_2004111114454891_lustre.1.4.0-phik/drivers/scsi/sd.c
21 ===================================================================
22 --- linux-2.6.5-SLES9_SP1_BRANCH_2004111114454891_lustre.1.4.0-phik.orig/drivers/scsi/sd.c 2004-11-11 07:28:28.000000000 -0800
23 +++ linux-2.6.5-SLES9_SP1_BRANCH_2004111114454891_lustre.1.4.0-phik/drivers/scsi/sd.c 2005-01-07 01:29:47.033727872 -0800
26 #include "scsi_logging.h"
28 +#if (defined(CONFIG_SD_IOSTATS) && defined(CONFIG_PROC_FS))
29 +# include <linux/proc_fs.h>
30 +# include <linux/seq_file.h>
33 + unsigned long long iostat_size;
34 + unsigned long long iostat_count;
37 +#define IOSTAT_NCOUNTERS 16
39 + iostat_counter_t iostat_read_histogram[IOSTAT_NCOUNTERS];
40 + iostat_counter_t iostat_write_histogram[IOSTAT_NCOUNTERS];
41 + struct timeval iostat_timeval;
44 +iostat_stats_t **sd_iostats;
45 +spinlock_t sd_iostats_lock;
46 +struct proc_dir_entry *sd_iostats_procdir;
47 +char sd_iostats_procdir_name[] = "sd_iostats";
49 +extern void sd_iostats_init(void);
50 +extern void sd_iostats_init_disk(struct gendisk *);
51 +extern void sd_iostats_fini(void);
52 +extern void sd_iostats_bump(int disk, unsigned int nsect, int iswrite);
54 +static inline void sd_iostats_init(void) {}
55 +static inline void sd_iostats_init_disk(struct gendisk *disk) {}
56 +static inline void sd_iostats_fini(void) {}
57 +static inline void sd_iostats_bump(int disk, unsigned int nsect, int iswrite) {}
61 * Remaining dev_t-handling stuff
64 #define SD_DISKS 32768 /* anything between 256 and 262144 */
68 * Time out in seconds for disks and Magneto-opticals (which are slower).
70 SCSI_LOG_HLQUEUE(2, printk("%s : block=%llu\n",
71 disk->disk_name, (unsigned long long)block));
73 + sd_iostats_bump(scsi_disk(disk)->index, this_count,
74 + rq_data_dir(SCpnt->request) == WRITE);
77 * If we have a 1K hardware sectorsize, prevent access to single
78 * 512 byte sectors. In theory we could handle this - in fact
80 scsi_set_medium_removal(sdev, SCSI_REMOVAL_PREVENT);
83 + sd_iostats_init_disk(disk);
87 @@ -1548,6 +1584,327 @@
91 +#if (defined(CONFIG_SD_IOSTATS) && defined(CONFIG_PROC_FS))
93 +sd_iostats_seq_show(struct seq_file *seq, void *v)
96 + struct gendisk *disk = seq->private;
97 + iostat_stats_t *stats;
98 + unsigned long long read_len;
99 + unsigned long long read_len_tot;
100 + unsigned long read_num;
101 + unsigned long read_num_tot;
102 + unsigned long long write_len;
103 + unsigned long long write_len_tot;
104 + unsigned long write_num;
105 + unsigned long write_num_tot;
109 + if (sd_iostats == NULL) {
110 + printk(KERN_ERR "sd_iostats_seq_show: NULL stats array\n");
114 + stats = sd_iostats[scsi_disk(disk)->index];
115 + if (stats == NULL) {
116 + printk(KERN_ERR "sd_iostats_seq_show: NULL stats entry\n");
120 + do_gettimeofday(&now);
121 + now.tv_sec -= stats->iostat_timeval.tv_sec;
122 + now.tv_usec -= stats->iostat_timeval.tv_usec;
123 + if (now.tv_usec < 0) {
124 + now.tv_usec += 1000000;
128 + /* this sampling races with updates */
129 + seq_printf(seq, "index: %lu snapshot_time: %lu.%06lu\n",
130 + scsi_disk(disk)->index, now.tv_sec, now.tv_usec);
132 + for (i = IOSTAT_NCOUNTERS - 1; i > 0; i--)
133 + if (stats->iostat_read_histogram[i].iostat_count != 0 ||
134 + stats->iostat_write_histogram[i].iostat_count != 0)
138 + seq_printf(seq, "%8s %8s %12s %8s %12s\n", "size",
139 + "reads", "total", "writes", "total");
141 + read_len_tot = write_len_tot = 0;
142 + read_num_tot = write_num_tot = 0;
143 + for (i = 0; i <= maxi; i++) {
144 + read_len = stats->iostat_read_histogram[i].iostat_size;
145 + read_len_tot += read_len;
146 + read_num = stats->iostat_read_histogram[i].iostat_count;
147 + read_num_tot += read_num;
149 + write_len = stats->iostat_write_histogram[i].iostat_size;
150 + write_len_tot += write_len;
151 + write_num = stats->iostat_write_histogram[i].iostat_count;
152 + write_num_tot += write_num;
154 + seq_printf (seq, "%8d %8lu %12llu %8lu %12llu\n",
155 + 512<<i, read_num, read_len, write_num, write_len);
158 + seq_printf(seq, "%8s %8lu %12llu %8lu %12llu\n", "total",
159 + read_num_tot, read_len_tot,
160 + write_num_tot, write_len_tot);
165 +sd_iostats_seq_start(struct seq_file *p, loff_t *pos)
167 + return (*pos == 0) ? (void *)1 : NULL;
171 +sd_iostats_seq_next(struct seq_file *p, void *v, loff_t *pos)
178 +sd_iostats_seq_stop(struct seq_file *p, void *v)
182 +static struct seq_operations sd_iostats_seqops = {
183 + .start = sd_iostats_seq_start,
184 + .stop = sd_iostats_seq_stop,
185 + .next = sd_iostats_seq_next,
186 + .show = sd_iostats_seq_show,
190 +sd_iostats_seq_open (struct inode *inode, struct file *file)
194 + rc = seq_open(file, &sd_iostats_seqops);
198 + ((struct seq_file *)file->private_data)->private = PDE(inode)->data;
203 +sd_iostats_seq_write(struct file *file, const char *buffer,
204 + size_t len, loff_t *off)
206 + struct seq_file *seq = file->private_data;
207 + struct gendisk *disk = seq->private;
208 + iostat_stats_t *stats = sd_iostats[scsi_disk(disk)->index];
209 + unsigned long flags;
212 + spin_lock_irqsave (&sd_iostats_lock, flags);
213 + memset (stats, 0, sizeof(*stats));
214 + do_gettimeofday(&stats->iostat_timeval);
215 + spin_unlock_irqrestore (&sd_iostats_lock, flags);
220 +static struct file_operations sd_iostats_proc_fops = {
221 + .owner = THIS_MODULE,
222 + .open = sd_iostats_seq_open,
224 + .write = sd_iostats_seq_write,
225 + .llseek = seq_lseek,
226 + .release = seq_release,
229 +extern struct proc_dir_entry *proc_scsi;
232 +sd_iostats_init(void)
236 + spin_lock_init(&sd_iostats_lock);
238 + sd_iostats = kmalloc(SD_STATS * sizeof(iostat_stats_t *), GFP_KERNEL);
239 + if (sd_iostats == NULL) {
240 + printk(KERN_WARNING "Can't keep sd iostats: "
241 + "ENOMEM allocating stats array size %ld\n",
242 + SD_STATS * sizeof(iostat_stats_t *));
246 + for (i = 0; i < SD_STATS; i++)
247 + sd_iostats[i] = NULL;
249 + if (proc_scsi == NULL) {
250 + printk(KERN_WARNING "No access to sd iostats: "
251 + "proc_scsi is NULL\n");
255 + sd_iostats_procdir = create_proc_entry(sd_iostats_procdir_name,
256 + S_IFDIR | S_IRUGO | S_IXUGO,
258 + if (sd_iostats_procdir == NULL) {
259 + printk(KERN_WARNING "No access to sd iostats: "
260 + "can't create /proc/scsi/%s\n", sd_iostats_procdir_name);
266 +sd_iostats_init_disk(struct gendisk *disk)
268 + struct proc_dir_entry *pde;
269 + unsigned long flags;
270 + iostat_stats_t *stats;
272 + if (sd_iostats == NULL ||
273 + sd_iostats_procdir == NULL)
276 + if (scsi_disk(disk)->index > SD_STATS) {
277 + printk(KERN_ERR "sd_iostats_init_disk: "
278 + "unexpected disk index %d(%d)\n",
279 + scsi_disk(disk)->index, SD_STATS);
283 + if (sd_iostats[scsi_disk(disk)->index] != NULL)
286 + stats = kmalloc(sizeof(*stats), GFP_KERNEL);
287 + if (stats == NULL) {
288 + printk(KERN_WARNING "Can't keep %s iostats: "
289 + "ENOMEM allocating stats size %ld\n",
290 + disk->disk_name, sizeof(*stats));
294 + memset (stats, 0, sizeof(*stats));
295 + do_gettimeofday(&stats->iostat_timeval);
297 + spin_lock_irqsave(&sd_iostats_lock, flags);
299 + if (sd_iostats[scsi_disk(disk)->index] != NULL) {
300 + spin_unlock_irqrestore(&sd_iostats_lock, flags);
305 + sd_iostats[scsi_disk(disk)->index] = stats;
307 + spin_unlock_irqrestore(&sd_iostats_lock, flags);
309 + pde = create_proc_entry(disk->disk_name, S_IRUGO | S_IWUSR,
310 + sd_iostats_procdir);
312 + printk(KERN_WARNING "Can't create /proc/scsi/%s/%s\n",
313 + sd_iostats_procdir_name, disk->disk_name);
315 + pde->proc_fops = &sd_iostats_proc_fops;
320 +static void sd_devname(unsigned int disknum, char *buffer)
323 + sprintf(buffer, "sd%c", 'a' + disknum);
328 + * For larger numbers of disks, we need to go to a new
331 + min1 = disknum / 26;
332 + min2 = disknum % 26;
333 + sprintf(buffer, "sd%c%c", 'a' + min1 - 1, 'a' + min2);
338 +sd_iostats_fini(void)
343 + if (sd_iostats_procdir != NULL) {
344 + for (i = 0; i < SD_STATS; i++) {
345 + sd_devname(i, name);
346 + remove_proc_entry(name, sd_iostats_procdir);
349 + if (proc_scsi == NULL) {
350 + printk(KERN_ERR "sd_iostats_fini: proc_scsi NULL\n");
353 + remove_proc_entry(sd_iostats_procdir_name,
356 + sd_iostats_procdir = NULL;
359 + if (sd_iostats != NULL) {
360 + for (i = 0; i < SD_STATS; i++) {
361 + if (sd_iostats[i] != NULL)
362 + kfree (sd_iostats[i]);
371 +sd_iostats_bump(int disk, unsigned int nsect, int iswrite)
373 + iostat_stats_t *stats;
374 + iostat_counter_t *counter;
377 + unsigned long irqflags;
379 + if (sd_iostats == NULL)
382 + if (disk < 0 || disk >= SD_STATS) {
383 + printk(KERN_ERR "sd_iostats_bump: unexpected disk index %d([0-%d])\n",
388 + for (bucket = 0, tmp = nsect; tmp > 1; bucket++)
391 + if (bucket >= IOSTAT_NCOUNTERS) {
392 + printk (KERN_ERR "sd_iostats_bump: nsect %d too big\n", nsect);
396 + spin_lock_irqsave(&sd_iostats_lock, irqflags);
398 + stats = sd_iostats[disk];
399 + if (stats != NULL) {
400 + counter = iswrite ?
401 + &stats->iostat_write_histogram[bucket] :
402 + &stats->iostat_read_histogram[bucket];
404 + counter->iostat_size += nsect;
405 + counter->iostat_count++;
408 + spin_unlock_irqrestore(&sd_iostats_lock, irqflags);
413 * init_sd - entry point for this driver (both when built in or when
415 @@ -1557,6 +1914,7 @@
416 static int __init init_sd(void)
421 SCSI_LOG_HLQUEUE(3, printk("init_sd: sd driver entry point\n"));
423 @@ -1567,7 +1925,10 @@
427 - return scsi_register_driver(&sd_template.gendrv);
428 + rc = scsi_register_driver(&sd_template.gendrv);
435 @@ -1581,6 +1942,7 @@
437 SCSI_LOG_HLQUEUE(3, printk("exit_sd: exiting sd driver\n"));
440 scsi_unregister_driver(&sd_template.gendrv);
441 for (i = 0; i < SD_MAJORS; i++)
442 unregister_blkdev(sd_major(i), "sd");
443 Index: linux-2.6.5-SLES9_SP1_BRANCH_2004111114454891_lustre.1.4.0-phik/drivers/scsi/scsi_proc.c
444 ===================================================================
445 --- linux-2.6.5-SLES9_SP1_BRANCH_2004111114454891_lustre.1.4.0-phik.orig/drivers/scsi/scsi_proc.c 2004-04-03 19:36:17.000000000 -0800
446 +++ linux-2.6.5-SLES9_SP1_BRANCH_2004111114454891_lustre.1.4.0-phik/drivers/scsi/scsi_proc.c 2005-01-07 00:15:53.905665776 -0800
448 /* 4K page size, but our output routines, use some slack for overruns */
449 #define PROC_BLOCK_SIZE (3*1024)
451 -static struct proc_dir_entry *proc_scsi;
452 +struct proc_dir_entry *proc_scsi;
453 +EXPORT_SYMBOL(proc_scsi);
455 /* Protect sht->present and sht->proc_dir */
456 static DECLARE_MUTEX(global_host_template_sem);