📄 sd_iostats-2.6-rhel5.patch
字号:
+ size_t len, loff_t *off)+{+ struct seq_file *seq = file->private_data;+ struct gendisk *disk = seq->private;+ iostat_stats_t *stats = sd_iostats[scsi_disk(disk)->index];+ unsigned long flags;+ unsigned long qdepth;+++ spin_lock_irqsave (&stats->iostat_lock, flags);+ qdepth = stats->iostat_queue_depth;+ memset (stats, 0, offsetof(iostat_stats_t, iostat_lock));+ do_gettimeofday(&stats->iostat_timeval);+ stats->iostat_queue_stamp = jiffies;+ stats->iostat_queue_depth = qdepth;+ spin_unlock_irqrestore (&stats->iostat_lock, flags);++ return len;+}++static struct file_operations sd_iostats_proc_fops = {+ .owner = THIS_MODULE,+ .open = sd_iostats_seq_open,+ .read = seq_read,+ .write = sd_iostats_seq_write,+ .llseek = seq_lseek,+ .release = seq_release,+};++extern struct proc_dir_entry *proc_scsi;++void+sd_iostats_init(void)+{+ int i;++ sd_iostats = kmalloc(SD_STATS * sizeof(iostat_stats_t *), GFP_KERNEL);+ if (sd_iostats == NULL) {+ printk(KERN_WARNING "Can't keep sd iostats: "+ "ENOMEM allocating stats array size %d\n",+ SD_STATS * sizeof(iostat_stats_t *));+ return;+ }++ for (i = 0; i < SD_STATS; i++)+ sd_iostats[i] = NULL;++ if (proc_scsi == NULL) {+ printk(KERN_WARNING "No access to sd iostats: "+ "proc_scsi is NULL\n");+ return;+ }++ sd_iostats_procdir = create_proc_entry(sd_iostats_procdir_name,+ S_IFDIR | S_IRUGO | S_IXUGO,+ proc_scsi);+ if (sd_iostats_procdir == NULL) {+ printk(KERN_WARNING "No access to sd iostats: "+ "can't create /proc/scsi/%s\n", sd_iostats_procdir_name);+ return;+ }+}++void+sd_iostats_init_disk(struct gendisk *disk)+{+ struct proc_dir_entry *pde;+ unsigned long flags;+ iostat_stats_t *stats;++ if (sd_iostats == NULL || sd_iostats_procdir == NULL)+ return;++ if (scsi_disk(disk)->index > SD_STATS) {+ printk(KERN_ERR "sd_iostats_init_disk: "+ "unexpected disk index %d(%d)\n",+ scsi_disk(disk)->index, SD_STATS);+ return;+ }++ if (sd_iostats[scsi_disk(disk)->index] != NULL)+ return;++ stats = kmalloc(sizeof(*stats), GFP_KERNEL);+ if (stats == NULL) {+ printk(KERN_WARNING "Can't keep %s iostats: "+ "ENOMEM allocating stats size %d\n", + disk->disk_name, sizeof(*stats));+ return;+ }++ memset (stats, 0, sizeof(*stats));+ do_gettimeofday(&stats->iostat_timeval);+ stats->iostat_queue_stamp = jiffies;+ spin_lock_init(&stats->iostat_lock);+++ spin_lock_irqsave(&stats->iostat_lock, flags);++ if (sd_iostats[scsi_disk(disk)->index] != NULL) {+ spin_unlock_irqrestore(&stats->iostat_lock, flags);+ kfree (stats);+ return;+ }++ sd_iostats[scsi_disk(disk)->index] = stats;++ spin_unlock_irqrestore(&stats->iostat_lock, flags);++ strncpy(stats->iostat_name, disk->disk_name,+ sizeof(stats->iostat_name)-1);++ pde = create_proc_entry(stats->iostat_name, S_IRUGO | S_IWUSR,+ sd_iostats_procdir);+ if (pde == NULL) {+ printk(KERN_WARNING "Can't create /proc/scsi/%s/%s\n",+ sd_iostats_procdir_name, disk->disk_name);+ } else {+ pde->proc_fops = &sd_iostats_proc_fops;+ pde->data = disk;+ }+}++void sd_iostats_fini(void)+{+ int i;++ if (sd_iostats == NULL)+ return;++ for (i = 0; i < SD_STATS; i++) {+ if (sd_iostats[i] == NULL)+ continue;+ if (sd_iostats_procdir != NULL)+ remove_proc_entry(sd_iostats[i]->iostat_name,+ sd_iostats_procdir);+ kfree(sd_iostats[i]);+ }++ if (proc_scsi != NULL && sd_iostats_procdir != NULL)+ remove_proc_entry(sd_iostats_procdir_name, proc_scsi);++ sd_iostats_procdir = NULL;+ kfree(sd_iostats);+ sd_iostats = NULL;+}++void sd_iostats_finish_req(struct scsi_cmnd *SCpnt)+{+ struct request *rq = SCpnt->request;+ iostat_stats_t *stats;+ unsigned long *tcounter;+ int tbucket;+ int tmp;+ unsigned long irqflags;+ int disk, i;++ disk = scsi_disk(rq->rq_disk)->index;++ if (sd_iostats == NULL)+ return;++ if (disk < 0 || disk >= SD_STATS) {+ printk(KERN_ERR "sd_iostats_bump: unexpected disk index "+ "%d([0-%d])\n", disk, SD_STATS);+ BUG();+ }++ stats = sd_iostats[disk];+ if (stats == NULL)+ return;++ tmp = jiffies - rq->start_time;+ for (tbucket = 0; tmp > 1; tbucket++)+ tmp >>= 1;+ if (tbucket >= IOSTAT_NCOUNTERS)+ tbucket = IOSTAT_NCOUNTERS - 1;+ //printk("%u ticks in D to %u\n", jiffies - rq->start_time, tbucket);++ tcounter = rq_data_dir(rq) == WRITE ? + &stats->iostat_wtime[tbucket] : &stats->iostat_rtime[tbucket];++ spin_lock_irqsave(&stats->iostat_lock, irqflags);++ /* update delay stats */+ (*tcounter)++;++ /* update queue depth stats */+ i = stats->iostat_queue_depth;+ if (i >= IOSTAT_NCOUNTERS)+ i = IOSTAT_NCOUNTERS - 1;+ stats->iostat_queue_ticks[i] += jiffies - stats->iostat_queue_stamp;+ stats->iostat_queue_ticks_sum += jiffies - stats->iostat_queue_stamp;+ stats->iostat_queue_depth--;++ /* update seek stats. XXX: not sure about nr_sectors */+ stats->iostat_sectors += rq->nr_sectors;+ stats->iostat_reqs++;+ if (rq->sector != stats->iostat_next_sector) {+ stats->iostat_seek_sectors += + rq->sector > stats->iostat_next_sector ?+ rq->sector - stats->iostat_next_sector :+ stats->iostat_next_sector - rq->sector;+ stats->iostat_seeks++;+ }+ stats->iostat_next_sector = rq->sector + rq->nr_sectors;++ stats->iostat_queue_stamp = jiffies;++ spin_unlock_irqrestore(&stats->iostat_lock, irqflags);+}++void sd_iostats_start_req(struct scsi_cmnd *SCpnt)+{+ struct request *rq = SCpnt->request;+ iostat_stats_t *stats;+ iostat_counter_t *counter;+ int bucket;+ int tbucket;+ int tmp;+ unsigned long irqflags;+ int disk, i;+ int nsect;++ disk = scsi_disk(rq->rq_disk)->index;++ if (sd_iostats == NULL)+ return;++ if (disk < 0 || disk >= SD_STATS) {+ printk(KERN_ERR "sd_iostats_bump: unexpected disk index %d([0-%d])\n",+ disk, SD_STATS);+ BUG();+ }++ stats = sd_iostats[disk];+ if (stats == NULL)+ return;++ nsect = SCpnt->request_bufflen >> 9;+ for (bucket = 0, tmp = nsect; tmp > 1; bucket++)+ tmp >>= 1;++ if (bucket >= IOSTAT_NCOUNTERS) {+ printk (KERN_ERR "sd_iostats_bump: nsect %d too big\n", nsect);+ BUG();+ }++ counter = rq_data_dir(rq) == WRITE ? + &stats->iostat_write_histogram[bucket] :+ &stats->iostat_read_histogram[bucket];++ tmp = jiffies - rq->start_time;+ for (tbucket = 0; tmp > 1; tbucket++)+ tmp >>= 1;+ if (tbucket >= IOSTAT_NCOUNTERS)+ tbucket = IOSTAT_NCOUNTERS - 1;+ //printk("%u ticks in Q to %u\n", jiffies - rq->start_time, tbucket);++ /* an ugly hack to know exact processing time. the right+ * solution is to add one more field to struct request+ * hopefully it will break nothing ... */+ rq->start_time = jiffies;++ spin_lock_irqsave(&stats->iostat_lock, irqflags);++ /* update queue depth stats */+ i = stats->iostat_queue_depth;+ if (i >= IOSTAT_NCOUNTERS)+ i = IOSTAT_NCOUNTERS - 1;+ stats->iostat_queue_ticks[i] += jiffies - stats->iostat_queue_stamp;+ stats->iostat_queue_ticks_sum += jiffies - stats->iostat_queue_stamp;+ stats->iostat_queue_depth++;++ /* update delay stats */+ if (rq_data_dir(rq) == WRITE) {+ stats->iostat_wtime_in_queue[tbucket]++;+ stats->iostat_write_reqs++;+ } else {+ stats->iostat_rtime_in_queue[tbucket]++;+ stats->iostat_read_reqs++;+ }++ /* update size stats */+ counter->iostat_size += nsect;+ counter->iostat_count++;++ stats->iostat_queue_stamp = jiffies;++ spin_unlock_irqrestore(&stats->iostat_lock, irqflags);+}+#endif+ /** * init_sd - entry point for this driver (both when built in or when * a module).@@ -1584,6 +2127,7 @@ static void sd_shutdown(struct device *d static int __init init_sd(void) { int majors = 0, i;+ int rc = 0; SCSI_LOG_HLQUEUE(3, printk("init_sd: sd driver entry point\n")); @@ -1594,7 +2138,10 @@ static int __init init_sd(void) if (!majors) return -ENODEV; - return scsi_register_driver(&sd_template.gendrv);+ rc = scsi_register_driver(&sd_template.gendrv);+ if (rc == 0)+ sd_iostats_init();+ return rc; } /**@@ -1608,6 +2155,7 @@ static void __exit exit_sd(void) SCSI_LOG_HLQUEUE(3, printk("exit_sd: exiting sd driver\n")); + sd_iostats_fini(); scsi_unregister_driver(&sd_template.gendrv); for (i = 0; i < SD_MAJORS; i++) unregister_blkdev(sd_major(i), "sd");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -