GIT 6b035fe3f174bc74c48e6f11bce31668beaf7339 git+ssh://master.kernel.org/pub/scm/linux/kernel/git/axboe/linux-2.6-block.git#for-linus commit 6b035fe3f174bc74c48e6f11bce31668beaf7339 Author: Brian King Date: Thu Feb 2 18:43:59 2006 +0100 [PATCH 1/1] blk: Fix SG_IO ioctl failure retry looping When issuing an SG_IO ioctl through sd that resulted in an unrecoverable error, a nearly infinite retry loop was discovered. This is due to the fact that the block layer SG_IO code is not setting up rq->retries. This patch also fixes up the sg_scsi_ioctl path. Signed-off-by: Brian King Signed-off-by: Jens Axboe commit 47142a3f6b16662a616dece5e0cc1db8ac87b124 Author: Jens Axboe Date: Thu Feb 2 18:42:27 2006 +0100 [PATCH] Fix nasty percpu data corruption With the patches added to make percpu data allocation more conservative, we see corruption when people use NR_CPUS instead of checking the possible map. This fixes it for SCSI and block. Anton has a patch for the rest of the kernel. Signed-off-by: Jens Axboe --- diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c index f9fc07e..2855cd1 100644 --- a/block/ll_rw_blk.c +++ b/block/ll_rw_blk.c @@ -3318,6 +3318,12 @@ static int blk_cpu_notify(struct notifie &__get_cpu_var(blk_cpu_done)); raise_softirq_irqoff(BLOCK_SOFTIRQ); local_irq_enable(); + } else if (action == CPU_ONLINE) { + int cpu = (unsigned long) hcpu; + + local_irq_disable(); + INIT_LIST_HEAD(&per_cpu(blk_cpu_done, cpu)); + local_irq_enable(); } return NOTIFY_OK; @@ -3453,7 +3459,7 @@ int __init blk_dev_init(void) iocontext_cachep = kmem_cache_create("blkdev_ioc", sizeof(struct io_context), 0, SLAB_PANIC, NULL, NULL); - for (i = 0; i < NR_CPUS; i++) + for_each_online_cpu(i) INIT_LIST_HEAD(&per_cpu(blk_cpu_done, i)); open_softirq(BLOCK_SOFTIRQ, blk_done_softirq, NULL); diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c index cc72210..24f7af9 100644 --- a/block/scsi_ioctl.c +++ b/block/scsi_ioctl.c @@ -310,6 +310,8 @@ static int sg_io(struct file *file, requ if (!rq->timeout) rq->timeout = BLK_DEFAULT_TIMEOUT; + rq->retries = 0; + start_time = jiffies; /* ignore return value. All information is passed back to caller @@ -427,6 +429,7 @@ static int sg_scsi_ioctl(struct file *fi rq->data = buffer; rq->data_len = bytes; rq->flags |= REQ_BLOCK_PC; + rq->retries = 0; blk_execute_rq(q, bd_disk, rq, 0); err = rq->errors & 0xff; /* only 8 bit SCSI status */ diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 245ca99..c551bb8 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -1245,7 +1245,7 @@ static int __init init_scsi(void) if (error) goto cleanup_sysctl; - for (i = 0; i < NR_CPUS; i++) + for_each_cpu(i) INIT_LIST_HEAD(&per_cpu(scsi_done_q, i)); devfs_mk_dir("scsi");