Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

[PATCH] cciss per disk queue

This patch adds per disk queue functionality to cciss. Sometime back I
submitted a patch but it looks like only part of what I needed. In the 2.6
kernel if we have more than one logical volume the driver will Oops during
rmmod. It seems all of the queues actually point back to the same queue.
So after deleting the first volume you hit a null pointer on the second
one.

This has been tested in our labs. There is no difference in performance,
it just fixes the Oops.

Signed-off-by: Mike Miller <mike.miller@hp.com>
Cc: Jens Axboe <axboe@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by

Mike Miller and committed by
Linus Torvalds
ad2b9312 eaaf9c68

+28 -25
+26 -23
drivers/block/cciss.c
··· 1135 1135 /* this is for the online array utilities */ 1136 1136 if (!drv->heads && i) 1137 1137 continue; 1138 - blk_queue_hardsect_size(host->queue, drv->block_size); 1138 + blk_queue_hardsect_size(drv->queue, drv->block_size); 1139 1139 set_capacity(disk, drv->nr_blocks); 1140 1140 add_disk(disk); 1141 1141 } ··· 1691 1691 cciss_read_capacity(h->ctlr, logvol, size_buff, 1, &total_size, &block_size); 1692 1692 cciss_geometry_inquiry(h->ctlr, logvol, 1, total_size, block_size, inq_buff, drv); 1693 1693 1694 - blk_queue_hardsect_size(h->queue, drv->block_size); 1694 + blk_queue_hardsect_size(drv->queue, drv->block_size); 1695 1695 set_capacity(disk, drv->nr_blocks); 1696 1696 1697 1697 kfree(size_buff); ··· 2248 2248 * them up. We will also keep track of the next queue to run so 2249 2249 * that every queue gets a chance to be started first. 2250 2250 */ 2251 - for (j=0; j < NWD; j++){ 2252 - int curr_queue = (start_queue + j) % NWD; 2251 + for (j=0; j < h->highest_lun + 1; j++){ 2252 + int curr_queue = (start_queue + j) % (h->highest_lun + 1); 2253 2253 /* make sure the disk has been added and the drive is real 2254 2254 * because this can be called from the middle of init_one. 2255 2255 */ 2256 - if(!(h->gendisk[curr_queue]->queue) || 2256 + if(!(h->drv[curr_queue].queue) || 2257 2257 !(h->drv[curr_queue].heads)) 2258 2258 continue; 2259 2259 blk_start_queue(h->gendisk[curr_queue]->queue); ··· 2264 2264 if ((find_first_zero_bit(h->cmd_pool_bits, NR_CMDS)) == NR_CMDS) 2265 2265 { 2266 2266 if (curr_queue == start_queue){ 2267 - h->next_to_run = (start_queue + 1) % NWD; 2267 + h->next_to_run = (start_queue + 1) % (h->highest_lun + 1); 2268 2268 goto cleanup; 2269 2269 } else { 2270 2270 h->next_to_run = curr_queue; 2271 2271 goto cleanup; 2272 2272 } 2273 2273 } else { 2274 - curr_queue = (curr_queue + 1) % NWD; 2274 + curr_queue = (curr_queue + 1) % (h->highest_lun + 1); 2275 2275 } 2276 2276 } 2277 2277 ··· 2279 2279 spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); 2280 2280 return IRQ_HANDLED; 2281 2281 } 2282 - 2283 2282 /* 2284 2283 * We cannot read the structure directly, for portablity we must use 2285 2284 * the io functions. ··· 2788 2789 } 2789 2790 2790 2791 spin_lock_init(&hba[i]->lock); 2791 - q = blk_init_queue(do_cciss_request, &hba[i]->lock); 2792 - if (!q) 2793 - goto clean4; 2794 - 2795 - q->backing_dev_info.ra_pages = READ_AHEAD; 2796 - hba[i]->queue = q; 2797 - q->queuedata = hba[i]; 2798 2792 2799 2793 /* Initialize the pdev driver private data. 2800 2794 have it point to hba[i]. */ ··· 2809 2817 2810 2818 cciss_procinit(i); 2811 2819 2820 + for(j=0; j < NWD; j++) { /* mfm */ 2821 + drive_info_struct *drv = &(hba[i]->drv[j]); 2822 + struct gendisk *disk = hba[i]->gendisk[j]; 2823 + 2824 + q = blk_init_queue(do_cciss_request, &hba[i]->lock); 2825 + if (!q) { 2826 + printk(KERN_ERR 2827 + "cciss: unable to allocate queue for disk %d\n", 2828 + j); 2829 + break; 2830 + } 2831 + drv->queue = q; 2832 + 2833 + q->backing_dev_info.ra_pages = READ_AHEAD; 2812 2834 blk_queue_bounce_limit(q, hba[i]->pdev->dma_mask); 2813 2835 2814 2836 /* This is a hardware imposed limit. */ ··· 2833 2827 2834 2828 blk_queue_max_sectors(q, 512); 2835 2829 2836 - 2837 - for(j=0; j<NWD; j++) { 2838 - drive_info_struct *drv = &(hba[i]->drv[j]); 2839 - struct gendisk *disk = hba[i]->gendisk[j]; 2840 - 2830 + q->queuedata = hba[i]; 2841 2831 sprintf(disk->disk_name, "cciss/c%dd%d", i, j); 2842 2832 sprintf(disk->devfs_name, "cciss/host%d/target%d", i, j); 2843 2833 disk->major = hba[i]->major; 2844 2834 disk->first_minor = j << NWD_SHIFT; 2845 2835 disk->fops = &cciss_fops; 2846 - disk->queue = hba[i]->queue; 2836 + disk->queue = q; 2847 2837 disk->private_data = drv; 2848 2838 /* we must register the controller even if no disks exist */ 2849 2839 /* this is for the online array utilities */ 2850 2840 if(!drv->heads && j) 2851 2841 continue; 2852 - blk_queue_hardsect_size(hba[i]->queue, drv->block_size); 2842 + blk_queue_hardsect_size(q, drv->block_size); 2853 2843 set_capacity(disk, drv->nr_blocks); 2854 2844 add_disk(disk); 2855 2845 } 2846 + 2856 2847 return(1); 2857 2848 2858 2849 clean4: ··· 2915 2912 for (j = 0; j < NWD; j++) { 2916 2913 struct gendisk *disk = hba[i]->gendisk[j]; 2917 2914 if (disk->flags & GENHD_FL_UP) 2915 + blk_cleanup_queue(disk->queue); 2918 2916 del_gendisk(disk); 2919 2917 } 2920 2918 2921 - blk_cleanup_queue(hba[i]->queue); 2922 2919 pci_free_consistent(hba[i]->pdev, NR_CMDS * sizeof(CommandList_struct), 2923 2920 hba[i]->cmd_pool, hba[i]->cmd_pool_dhandle); 2924 2921 pci_free_consistent(hba[i]->pdev, NR_CMDS * sizeof( ErrorInfo_struct),
+2 -2
drivers/block/cciss.h
··· 29 29 { 30 30 __u32 LunID; 31 31 int usage_count; 32 + struct request_queue *queue; 32 33 sector_t nr_blocks; 33 34 int block_size; 34 35 int heads; ··· 73 72 unsigned int maxQsinceinit; 74 73 unsigned int maxSG; 75 74 spinlock_t lock; 76 - struct request_queue *queue; 77 75 78 76 //* pointers to command and error info pool */ 79 77 CommandList_struct *cmd_pool; ··· 260 260 struct access_method *access; 261 261 }; 262 262 263 - #define CCISS_LOCK(i) (hba[i]->queue->queue_lock) 263 + #define CCISS_LOCK(i) (&hba[i]->lock) 264 264 265 265 #endif /* CCISS_H */ 266 266