I have seen this problem for a long time now (and it has been reported on this list before-months ago). My TODO list of bugs to investigate has grown too large so I needed to get this one off my list. the offending code is: "linux/drivers/scsi/sd.c" 1353/1393 (test9-2) > for (i = 0; i <= (sd_template.dev_max - 1) / SCSI_DISKS_PER_MAJOR; i++) > devfs_unregister_blkdev(SD_MAJOR(i), "sd"); This code will do nasty things if td_template.dev_max=0, namely loop for a very long time. The condition becomes: > for (i = 0; i <= (sd_template.dev_max - 1) / SCSI_DISKS_PER_MAJOR; i++) > = for (i = 0; i <= (0 - 1) / 16; i++) > = for (i = 0; i <= 0xFFFFFFFF / 16; i++) The solution seems to be to use the macros and make the loop look like: >#define N_USED_SCSI_DISKS (sd_template.dev_max + SCSI_DISKS_PER_MAJOR -1) >#define N_USED_SD_MAJORS (N_USED_SCSI_DISKS / SCSI_DISKS_PER_MAJOR) NEW_CODE: > for (i = 0; i < N_USED_SD_MAJORS; i++) > devfs_unregister_blkdev(SD_MAJOR(i), "sd"); Seems like a good idea to use the macros that are already defined. This offending loop seems to be in the code 4 times (lines 1033, 1145, 1353, 1382) I have experienced this problem in 2.4.0test kernels but a quick inspection of 2.2.x reveals that it has the same code and probably the same problem. Attacted are fixes for test9-2 and 2.2.17. This is my first patch to the list so please give it a glance before applying. I have tested this patch only on a machine without scsi disks. -jeff ------------------------------------------------------------------------ Jeff Raubitschek DynaByte Systems [EMAIL PROTECTED]
--- linux-2.2.17/drivers/scsi/sd.c Wed Jun 7 17:26:43 2000 +++ linux.fixed/drivers/scsi/sd.c Mon Sep 18 09:02:14 2000 @@ -1513,7 +1513,7 @@ sd_template.dev_max = N_SD_MAJORS * SCSI_DISKS_PER_MAJOR; if(!sd_registered) { - for (i=0; i <= (sd_template.dev_max - 1) / SCSI_DISKS_PER_MAJOR; i++) { + for (i=0; i < N_USED_SD_MAJORS; i++) { if (register_blkdev(SD_MAJOR(i),"sd",&sd_fops)) { printk("Unable to get major %d for SCSI disk\n", SD_MAJOR(i)); return 1; @@ -1586,7 +1586,7 @@ struct gendisk *gendisk; int i; - for (i=0; i <= (sd_template.dev_max - 1) / SCSI_DISKS_PER_MAJOR; i++) { + for (i=0; i < N_USED_SD_MAJORS; i++) { /* FIXME: After 2.2 we should implement multiple sd queues */ blk_dev[SD_MAJOR(i)].request_fn = DEVICE_REQUEST; if (i) blk_dev[SD_MAJOR(i)].queue = sd_get_queue; @@ -1793,7 +1793,7 @@ scsi_unregister_module(MODULE_SCSI_DEV, &sd_template); - for (i=0; i <= (sd_template.dev_max - 1) / SCSI_DISKS_PER_MAJOR; i++) + for (i=0; i < N_USED_SD_MAJORS; i++) unregister_blkdev(SD_MAJOR(i),"sd"); sd_registered--; @@ -1826,7 +1826,7 @@ } - for (i=0; i <= (sd_template.dev_max - 1) / SCSI_DISKS_PER_MAJOR; i++) { + for (i=0; i < N_USED_SD_MAJORS; i++) { blk_dev[SD_MAJOR(i)].request_fn = NULL; blk_size[SD_MAJOR(i)] = NULL; hardsect_size[SD_MAJOR(i)] = NULL;
--- linux.buggy/drivers/scsi/sd.c Mon Sep 18 08:42:05 2000 +++ linux/drivers/scsi/sd.c Mon Sep 18 08:44:37 2000 @@ -1030,7 +1030,7 @@ sd_template.dev_max = N_SD_MAJORS * SCSI_DISKS_PER_MAJOR; if (!sd_registered) { - for (i = 0; i <= (sd_template.dev_max - 1) / SCSI_DISKS_PER_MAJOR; i++) { + for (i = 0; i < N_USED_SD_MAJORS; i++) { if (devfs_register_blkdev(SD_MAJOR(i), "sd", &sd_fops)) { printk("Unable to get major %d for SCSI disk\n", SD_MAJOR(i)); return 1; @@ -1142,7 +1142,7 @@ struct gendisk *gendisk; int i; - for (i = 0; i <= (sd_template.dev_max - 1) / SCSI_DISKS_PER_MAJOR; i++) { + for (i = 0; i < N_USED_SD_MAJORS; i++) { blk_dev[SD_MAJOR(i)].queue = sd_find_queue; } for (gendisk = gendisk_head; gendisk != NULL; gendisk = gendisk->next) @@ -1350,7 +1350,7 @@ scsi_unregister_module(MODULE_SCSI_DEV, &sd_template); - for (i = 0; i <= (sd_template.dev_max - 1) / SCSI_DISKS_PER_MAJOR; i++) + for (i = 0; i < N_USED_SD_MAJORS; i++) devfs_unregister_blkdev(SD_MAJOR(i), "sd"); sd_registered--; @@ -1379,7 +1379,7 @@ removed > N_USED_SD_MAJORS ? "total" : "just", removed); } - for (i = 0; i <= (sd_template.dev_max - 1) / SCSI_DISKS_PER_MAJOR; i++) { + for (i = 0; i < N_USED_SD_MAJORS; i++) { blk_size[SD_MAJOR(i)] = NULL; hardsect_size[SD_MAJOR(i)] = NULL; read_ahead[SD_MAJOR(i)] = 0;