2001-07-31 00:31:09

by Richard Gooch

[permalink] [raw]
Subject: [RFT] Support for ~2144 SCSI discs

Hi, all. Below is a patch that adds support for large numbers of
SCSI discs (approximately 2144). I'd like people to try this out. I'm
not doing my normal devfs-patch-v??? thing because this is completely
untested (I'm away from my SCSI boxes), and I don't want to put a
possibly FS-corrupting patch on my ftp archive. The code does compile
and link, though.

There are 3 cases I'd like to have tested:
- people with 1 to 16 SCSI discs
- people with 17 to 128 SCSI discs
- people with >128 SCSI discs

because each of these exercises a slightly different setup path.
Please send success or failure reports to me.

REMINDER: be careful with this patch. It could corrupt your FS.

Regards,

Richard....
Permanent: [email protected]
Current: [email protected]

diff -urN linux-2.4.7/Documentation/Configure.help linux/Documentation/Configure.help
--- linux-2.4.7/Documentation/Configure.help Thu Jul 19 20:48:15 2001
+++ linux/Documentation/Configure.help Mon Jul 23 01:19:24 2001
@@ -5410,6 +5410,17 @@
located on a SCSI disk. In this case, do not compile the driver for
your SCSI host adapter (below) as a module either.

+Many SCSI Discs support
+CONFIG_SD_MANY
+ This allows you to support a very large number of SCSI discs
+ (approximately 2144). You will also need to set CONFIG_DEVFS_FS=y
+ later. This option may consume all unassigned block majors
+ (i.e. those which do not have an allocation in
+ Documentation/devices.txt). Enabling this will consume a few extra
+ kilobytes of kernel memory.
+
+ Unless you have a large storage array, say N.
+
Extra SCSI Disks
CONFIG_SD_EXTRA_DEVS
This controls the amount of additional space allocated in tables for
diff -urN linux-2.4.7/Documentation/filesystems/devfs/ChangeLog linux/Documentation/filesystems/devfs/ChangeLog
--- linux-2.4.7/Documentation/filesystems/devfs/ChangeLog Wed Jul 11 17:55:41 2001
+++ linux/Documentation/filesystems/devfs/ChangeLog Mon Jul 30 19:13:00 2001
@@ -1675,3 +1675,13 @@
- Fixed number leak for /dev/cdroms/cdrom%d

- Fixed number leak for /dev/discs/disc%d
+===============================================================================
+Changes for patch v183
+
+- Fixed bug in <devfs_setup> which could hang boot process
+===============================================================================
+Changes for patch v184
+
+- Support large numbers of SCSI discs (~2144)
+
+- Documentation typo fix for fs/devfs/util.c
diff -urN linux-2.4.7/drivers/scsi/Config.in linux/drivers/scsi/Config.in
--- linux-2.4.7/drivers/scsi/Config.in Thu Jul 5 14:28:16 2001
+++ linux/drivers/scsi/Config.in Mon Jul 23 01:19:47 2001
@@ -3,7 +3,8 @@
dep_tristate ' SCSI disk support' CONFIG_BLK_DEV_SD $CONFIG_SCSI

if [ "$CONFIG_BLK_DEV_SD" != "n" ]; then
- int 'Maximum number of SCSI disks that can be loaded as modules' CONFIG_SD_EXTRA_DEVS 40
+ bool ' Many (~2144) SCSI discs support (requires devfs)' CONFIG_SD_MANY
+ int ' Maximum number of SCSI disks that can be loaded as modules' CONFIG_SD_EXTRA_DEVS 40
fi

dep_tristate ' SCSI tape support' CONFIG_CHR_DEV_ST $CONFIG_SCSI
diff -urN linux-2.4.7/drivers/scsi/hosts.h linux/drivers/scsi/hosts.h
--- linux-2.4.7/drivers/scsi/hosts.h Fri Jul 20 15:55:46 2001
+++ linux/drivers/scsi/hosts.h Mon Jul 30 19:20:27 2001
@@ -506,9 +506,8 @@
const char * tag;
struct module * module; /* Used for loadable modules */
unsigned char scsi_type;
- unsigned int major;
- unsigned int min_major; /* Minimum major in range. */
- unsigned int max_major; /* Maximum major in range. */
+ unsigned int *majors; /* Array of majors used by driver */
+ unsigned int num_majors; /* Number of majors used by driver */
unsigned int nr_dev; /* Number currently attached */
unsigned int dev_noticed; /* Number of devices detected. */
unsigned int dev_max; /* Current size of arrays */
diff -urN linux-2.4.7/drivers/scsi/osst.c linux/drivers/scsi/osst.c
--- linux-2.4.7/drivers/scsi/osst.c Fri Jul 20 00:18:15 2001
+++ linux/drivers/scsi/osst.c Mon Jul 30 17:57:27 2001
@@ -160,7 +160,6 @@
name: "OnStream tape",
tag: "osst",
scsi_type: TYPE_TAPE,
- major: OSST_MAJOR,
detect: osst_detect,
init: osst_init,
attach: osst_attach,
diff -urN linux-2.4.7/drivers/scsi/scsi_lib.c linux/drivers/scsi/scsi_lib.c
--- linux-2.4.7/drivers/scsi/scsi_lib.c Thu Jul 19 23:48:04 2001
+++ linux/drivers/scsi/scsi_lib.c Mon Jul 30 17:52:35 2001
@@ -769,25 +769,10 @@
* Search for a block device driver that supports this
* major.
*/
- if (spnt->blk && spnt->major == major) {
- return spnt;
- }
- /*
- * I am still not entirely satisfied with this solution,
- * but it is good enough for now. Disks have a number of
- * major numbers associated with them, the primary
- * 8, which we test above, and a secondary range of 7
- * different consecutive major numbers. If this ever
- * becomes insufficient, then we could add another function
- * to the structure, and generalize this completely.
- */
- if( spnt->min_major != 0
- && spnt->max_major != 0
- && major >= spnt->min_major
- && major <= spnt->max_major )
- {
- return spnt;
- }
+ int i;
+ if (!spnt->blk || !spnt->majors) continue;
+ for (i = 0; i < spnt->num_majors; ++i)
+ if (spnt->majors[i] == major) return spnt;
}
return NULL;
}
diff -urN linux-2.4.7/drivers/scsi/sd.c linux/drivers/scsi/sd.c
--- linux-2.4.7/drivers/scsi/sd.c Thu Jul 5 14:28:17 2001
+++ linux/drivers/scsi/sd.c Mon Jul 30 20:10:58 2001
@@ -28,6 +28,8 @@
*
* Modified by Alex Davis <[email protected]>
* Fix problem where removable media could be ejected after sd_open.
+ *
+ * Modified by Richard Gooch [email protected] to support >128 discs.
*/

#include <linux/config.h>
@@ -65,7 +67,7 @@
* static const char RCSid[] = "$Header:";
*/

-#define SD_MAJOR(i) (!(i) ? SCSI_DISK0_MAJOR : SCSI_DISK1_MAJOR-1+(i))
+#define SD_MAJOR(i) sd_template.majors[(i)]

#define SCSI_DISKS_PER_MAJOR 16
#define SD_MAJOR_NUMBER(i) SD_MAJOR((i) >> 8)
@@ -108,12 +110,6 @@
name:"disk",
tag:"sd",
scsi_type:TYPE_DISK,
- major:SCSI_DISK0_MAJOR,
- /*
- * Secondary range of majors that this driver handles.
- */
- min_major:SCSI_DISK1_MAJOR,
- max_major:SCSI_DISK7_MAJOR,
blk:1,
detect:sd_detect,
init:sd_init,
@@ -123,6 +119,19 @@
init_command:sd_init_command,
};

+#ifdef CONFIG_SD_MANY
+static inline int sd_devnum_to_index (int devnum)
+{
+ int i, major = MAJOR (devnum);
+
+ for (i = 0; i < sd_template.num_majors; ++i)
+ {
+ if (sd_template.majors[i] != major) continue;
+ return (i << 4) | (MINOR (i) >> 4);
+ }
+ return -ENODEV;
+}
+#endif

static void rw_intr(Scsi_Cmnd * SCpnt);

@@ -1043,6 +1052,41 @@
return i;
}

+static int sd_alloc_majors (void)
+/* Allocate as many majors as required
+ */
+{
+ int i, major;
+
+ if ( ( sd_template.majors =
+ kmalloc (sizeof sd_template.majors * N_USED_SD_MAJORS,
+ GFP_ATOMIC) ) == NULL ) {
+ printk ("sd.c: unable to allocate major array\n");
+ return -ENOMEM;
+ }
+ sd_template.majors[0] = SCSI_DISK0_MAJOR;
+ for (i = 1; (i < N_USED_SD_MAJORS) && (i <N_SD_PREASSIGNED_MAJORS);++i)
+ sd_template.majors[i] = SCSI_DISK1_MAJOR + i - 1;
+ for (; (i >= N_SD_PREASSIGNED_MAJORS) && (i < N_USED_SD_MAJORS); ++i) {
+ if ( ( major = devfs_alloc_major (DEVFS_SPECIAL_BLK) ) < 0 )
+ break;
+ sd_template.majors[i] = major;
+ }
+ sd_template.dev_max = i * SCSI_DISKS_PER_MAJOR;
+ sd_template.num_majors = i;
+ return 0;
+} /* End Function sd_alloc_majors */
+
+static void sd_dealloc_majors (void)
+/* Deallocate all the allocated majors
+ */
+{
+ int i;
+
+ for (i = sd_template.num_majors - 1; i >= N_SD_PREASSIGNED_MAJORS; --i)
+ devfs_dealloc_major (DEVFS_SPECIAL_BLK, sd_template.majors[i]);
+} /* End Function sd_dealloc_majors */
+
/*
* The sd_init() function looks at all SCSI drives present, determines
* their size, and reads partition table entries for them.
@@ -1057,16 +1101,16 @@
if (sd_template.dev_noticed == 0)
return 0;

- if (!rscsi_disks)
+ if (!rscsi_disks) {
sd_template.dev_max = sd_template.dev_noticed + SD_EXTRA_DEVS;
-
- if (sd_template.dev_max > N_SD_MAJORS * SCSI_DISKS_PER_MAJOR)
- sd_template.dev_max = N_SD_MAJORS * SCSI_DISKS_PER_MAJOR;
+ if ( !sd_alloc_majors() ) return 1;
+ }

if (!sd_registered) {
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));
+ sd_dealloc_majors();
return 1;
}
}
@@ -1166,6 +1210,7 @@
for (i = 0; i < N_USED_SD_MAJORS; i++) {
devfs_unregister_blkdev(SD_MAJOR(i), "sd");
}
+ sd_dealloc_majors();
sd_registered--;
return 1;
}
@@ -1373,6 +1418,7 @@

scsi_unregister_module(MODULE_SCSI_DEV, &sd_template);

+ sd_dealloc_majors();
for (i = 0; i < N_USED_SD_MAJORS; i++)
devfs_unregister_blkdev(SD_MAJOR(i), "sd");

diff -urN linux-2.4.7/drivers/scsi/sd.h linux/drivers/scsi/sd.h
--- linux-2.4.7/drivers/scsi/sd.h Fri Jul 20 15:55:46 2001
+++ linux/drivers/scsi/sd.h Mon Jul 30 20:09:12 2001
@@ -42,10 +42,14 @@
*/
extern kdev_t sd_find_target(void *host, int tgt);

-#define N_SD_MAJORS 8
+#define N_SD_PREASSIGNED_MAJORS 8

+#ifdef CONFIG_SD_MANY
+#define SD_PARTITION(i) ((sd_devnum_to_index((i)) << 4) | ((i)&0x0f))
+#else
#define SD_MAJOR_MASK (N_SD_MAJORS - 1)
#define SD_PARTITION(i) (((MAJOR(i) & SD_MAJOR_MASK) << 8) | (MINOR(i) & 255))
+#endif

#endif

diff -urN linux-2.4.7/drivers/scsi/sg.c linux/drivers/scsi/sg.c
--- linux-2.4.7/drivers/scsi/sg.c Wed Jul 4 18:39:28 2001
+++ linux/drivers/scsi/sg.c Mon Jul 30 17:57:52 2001
@@ -123,7 +123,6 @@
{
tag:"sg",
scsi_type:0xff,
- major:SCSI_GENERIC_MAJOR,
detect:sg_detect,
init:sg_init,
finish:sg_finish,
diff -urN linux-2.4.7/drivers/scsi/sr.c linux/drivers/scsi/sr.c
--- linux-2.4.7/drivers/scsi/sr.c Thu Jul 5 14:28:17 2001
+++ linux/drivers/scsi/sr.c Mon Jul 30 17:59:33 2001
@@ -69,12 +69,15 @@

static int sr_init_command(Scsi_Cmnd *);

+static unsigned int sr_major = SCSI_CDROM_MAJOR;
+
static struct Scsi_Device_Template sr_template =
{
name:"cdrom",
tag:"sr",
scsi_type:TYPE_ROM,
- major:SCSI_CDROM_MAJOR,
+ majors:&sr_major,
+ num_majors:1,
blk:1,
detect:sr_detect,
init:sr_init,
diff -urN linux-2.4.7/drivers/scsi/st.c linux/drivers/scsi/st.c
--- linux-2.4.7/drivers/scsi/st.c Fri Jul 20 00:16:32 2001
+++ linux/drivers/scsi/st.c Mon Jul 30 17:58:22 2001
@@ -160,7 +160,6 @@
name:"tape",
tag:"st",
scsi_type:TYPE_TAPE,
- major:SCSI_TAPE_MAJOR,
detect:st_detect,
init:st_init,
attach:st_attach,
diff -urN linux-2.4.7/fs/devfs/base.c linux/fs/devfs/base.c
--- linux-2.4.7/fs/devfs/base.c Wed Jul 11 17:55:41 2001
+++ linux/fs/devfs/base.c Mon Jul 30 19:10:41 2001
@@ -511,6 +511,9 @@
Removed broken devnum allocation and use <devfs_alloc_devnum>.
Fixed old devnum leak by calling new <devfs_dealloc_devnum>.
v0.107
+ 20010712 Richard Gooch <[email protected]>
+ Fixed bug in <devfs_setup> which could hang boot process.
+ v0.108
*/
#include <linux/types.h>
#include <linux/errno.h>
@@ -543,7 +546,7 @@
#include <asm/bitops.h>
#include <asm/atomic.h>

-#define DEVFS_VERSION "0.107 (20010709)"
+#define DEVFS_VERSION "0.108 (20010712)"

#define DEVFS_NAME "devfs"

@@ -1342,12 +1345,12 @@
return NULL;
}
}
- de->u.fcb.autogen = 0;
+ de->u.fcb.autogen = FALSE;
if ( S_ISCHR (mode) || S_ISBLK (mode) )
{
de->u.fcb.u.device.major = major;
de->u.fcb.u.device.minor = minor;
- de->u.fcb.autogen = (devnum == NODEV) ? 0 : 1;
+ de->u.fcb.autogen = (devnum == NODEV) ? FALSE : TRUE;
}
else if ( S_ISREG (mode) ) de->u.fcb.u.file.size = 0;
else
@@ -1418,7 +1421,7 @@
MKDEV (de->u.fcb.u.device.major,
de->u.fcb.u.device.minor) );
}
- de->u.fcb.autogen = 0;
+ de->u.fcb.autogen = FALSE;
return;
}
if (S_ISLNK (de->mode) && de->registered)
@@ -2063,6 +2066,7 @@
{"show", OPTION_SHOW, &boot_options},
{"only", OPTION_ONLY, &boot_options},
{"mount", OPTION_MOUNT, &boot_options},
+ {NULL, 0, NULL}
};

while ( (*str != '\0') && !isspace (*str) )
@@ -2074,7 +2078,7 @@
invert = 1;
str += 2;
}
- for (i = 0; i < sizeof (devfs_options_tab); i++)
+ for (i = 0; devfs_options_tab[i].name != NULL; i++)
{
int len = strlen (devfs_options_tab[i].name);

diff -urN linux-2.4.7/fs/devfs/util.c linux/fs/devfs/util.c
--- linux-2.4.7/fs/devfs/util.c Wed Jul 11 17:55:41 2001
+++ linux/fs/devfs/util.c Mon Jul 30 18:28:12 2001
@@ -39,6 +39,8 @@
Created <devfs_*alloc_major> and <devfs_*alloc_devnum>.
20010710 Richard Gooch <[email protected]>
Created <devfs_*alloc_unique_number>.
+ 20010730 Richard Gooch <[email protected]>
+ Documentation typo fix.
*/
#include <linux/module.h>
#include <linux/init.h>
@@ -214,7 +216,7 @@

/**
* devfs_alloc_major - Allocate a major number.
- * @type: The type of the major (DEVFS_SPECIAL_CHR or DEVFS_SPECIAL_BLOCK)
+ * @type: The type of the major (DEVFS_SPECIAL_CHR or DEVFS_SPECIAL_BLK)

* Returns the allocated major, else -1 if none are available.
* This routine is thread safe and does not block.
@@ -238,7 +240,7 @@

/**
* devfs_dealloc_major - Deallocate a major number.
- * @type: The type of the major (DEVFS_SPECIAL_CHR or DEVFS_SPECIAL_BLOCK)
+ * @type: The type of the major (DEVFS_SPECIAL_CHR or DEVFS_SPECIAL_BLK)
* @major: The major number.
* This routine is thread safe and does not block.
*/
@@ -282,7 +284,7 @@

/**
* devfs_alloc_devnum - Allocate a device number.
- * @type: The type (DEVFS_SPECIAL_CHR or DEVFS_SPECIAL_BLOCK).
+ * @type: The type (DEVFS_SPECIAL_CHR or DEVFS_SPECIAL_BLK).
*
* Returns the allocated device number, else NODEV if none are available.
* This routine is thread safe and may block.
@@ -347,7 +349,7 @@

/**
* devfs_dealloc_devnum - Dellocate a device number.
- * @type: The type (DEVFS_SPECIAL_CHR or DEVFS_SPECIAL_BLOCK).
+ * @type: The type (DEVFS_SPECIAL_CHR or DEVFS_SPECIAL_BLK).
* @devnum: The device number.
*
* This routine is thread safe and does not block.
diff -urN linux-2.4.7/include/linux/blk.h linux/include/linux/blk.h
--- linux-2.4.7/include/linux/blk.h Mon Jul 30 19:20:01 2001
+++ linux/include/linux/blk.h Mon Jul 30 20:05:18 2001
@@ -144,7 +144,11 @@

#define DEVICE_NAME "scsidisk"
#define TIMEOUT_VALUE (2*HZ)
+#ifdef CONFIG_SD_MANY
+#define DEVICE_NR(device) sd_devnum_to_index((device))
+#else
#define DEVICE_NR(device) (((MAJOR(device) & SD_MAJOR_MASK) << (8 - 4)) + (MINOR(device) >> 4))
+#endif

/* Kludge to use the same number for both char and block major numbers */
#elif (MAJOR_NR == MD_MAJOR) && defined(MD_DRIVER)


2001-07-31 07:44:58

by Jeremy Higdon

[permalink] [raw]
Subject: Re: [RFT] Support for ~2144 SCSI discs

With the sard patch and a 64 bit system, you start having
trouble at around 103 configured disks, because of the following
line in sd_init() (sd.c), because kmalloc doesn't like allocating
large chunks of memory:

sd = kmalloc((sd_template.dev_max << 4) *
sizeof(struct hd_struct),
GFP_ATOMIC);

Without sard, you'd have problems past 512 disks.


With the sard patch, the hd_struct looks like the following:

struct hd_struct {
long start_sect;
long nr_sects;
devfs_handle_t de; /* primary (master) devfs entry */

int number; /* stupid old code wastes space */

/* Performance stats: */
unsigned int ios_in_flight;
unsigned int io_ticks;
unsigned int last_idle_time;
unsigned int last_queue_change;
unsigned int aveq;

unsigned int rd_ios;
unsigned int rd_merges;
unsigned int rd_ticks;
unsigned int rd_sectors;
unsigned int wr_ios;
unsigned int wr_merges;
unsigned int wr_ticks;
unsigned int wr_sectors;
};


The caveat is that I'm looking at a patch that is a few months old (I
couldn't find where the latest version of the kernel patch is).

jeremy

2001-07-31 12:26:09

by Richard Gooch

[permalink] [raw]
Subject: Re: [RFT] Support for ~2144 SCSI discs

Jeremy Higdon writes:
> With the sard patch and a 64 bit system, you start having
> trouble at around 103 configured disks, because of the following

So even without my patch, sard doesn't support the previous limit of
128 devices.

> line in sd_init() (sd.c), because kmalloc doesn't like allocating
> large chunks of memory:
>
> sd = kmalloc((sd_template.dev_max << 4) *
> sizeof(struct hd_struct),
> GFP_ATOMIC);
>
> Without sard, you'd have problems past 512 disks.

Yes, when I was coding up the patch I noticed the use of GFP_ATOMIC in
the allocation calls. I have two questions:
- can we use GFP_KERNEL instead (why use GFP_ATOMIC)
- can we switch to vmalloc() instead of kmalloc()?

> With the sard patch, the hd_struct looks like the following:
>
> struct hd_struct {
> long start_sect;
> long nr_sects;
> devfs_handle_t de; /* primary (master) devfs entry */
>
> int number; /* stupid old code wastes space */
>
> /* Performance stats: */
> unsigned int ios_in_flight;
> unsigned int io_ticks;
> unsigned int last_idle_time;
> unsigned int last_queue_change;
> unsigned int aveq;
>
> unsigned int rd_ios;
> unsigned int rd_merges;
> unsigned int rd_ticks;
> unsigned int rd_sectors;
> unsigned int wr_ios;
> unsigned int wr_merges;
> unsigned int wr_ticks;
> unsigned int wr_sectors;
> };
>
> The caveat is that I'm looking at a patch that is a few months old (I
> couldn't find where the latest version of the kernel patch is).

Do the stats have to be kept on a per-partition basic? What about
per-device instead?

Regards,

Richard....
Permanent: [email protected]
Current: [email protected]

2001-07-31 14:14:31

by Eric Youngdale

[permalink] [raw]
Subject: Re: [RFT] Support for ~2144 SCSI discs


FYI - At some point in the 2.5 series I would like to do some serious
surgery on the sd datastructures - this will mainly remove load order
dependencies and eliminate the need for CONFIG_SD_EXTRA. I believe that
some of the work that Jens has already started on the blk device layer will
make support for very large numbers of disks much easier.

-Eric

----- Original Message -----
From: "Richard Gooch" <[email protected]>
To: <[email protected]>; <[email protected]>
Cc: <[email protected]>
Sent: Monday, July 30, 2001 8:30 PM
Subject: [RFT] Support for ~2144 SCSI discs


> Hi, all. Below is a patch that adds support for large numbers of
> SCSI discs (approximately 2144). I'd like people to try this out. I'm
> not doing my normal devfs-patch-v??? thing because this is completely
> untested (I'm away from my SCSI boxes), and I don't want to put a
> possibly FS-corrupting patch on my ftp archive. The code does compile
> and link, though.
>
> There are 3 cases I'd like to have tested:
> - people with 1 to 16 SCSI discs
> - people with 17 to 128 SCSI discs
> - people with >128 SCSI discs
>
> because each of these exercises a slightly different setup path.
> Please send success or failure reports to me.
>
> REMINDER: be careful with this patch. It could corrupt your FS.
>
> Regards,
>
> Richard....
> Permanent: [email protected]
> Current: [email protected]
>
> diff -urN linux-2.4.7/Documentation/Configure.help
linux/Documentation/Configure.help
> --- linux-2.4.7/Documentation/Configure.help Thu Jul 19 20:48:15 2001
> +++ linux/Documentation/Configure.help Mon Jul 23 01:19:24 2001
> @@ -5410,6 +5410,17 @@
> located on a SCSI disk. In this case, do not compile the driver for
> your SCSI host adapter (below) as a module either.
>
> +Many SCSI Discs support
> +CONFIG_SD_MANY
> + This allows you to support a very large number of SCSI discs
> + (approximately 2144). You will also need to set CONFIG_DEVFS_FS=y
> + later. This option may consume all unassigned block majors
> + (i.e. those which do not have an allocation in
> + Documentation/devices.txt). Enabling this will consume a few extra
> + kilobytes of kernel memory.
> +
> + Unless you have a large storage array, say N.
> +
> Extra SCSI Disks
> CONFIG_SD_EXTRA_DEVS
> This controls the amount of additional space allocated in tables for
> diff -urN linux-2.4.7/Documentation/filesystems/devfs/ChangeLog
linux/Documentation/filesystems/devfs/ChangeLog
> --- linux-2.4.7/Documentation/filesystems/devfs/ChangeLog Wed Jul 11
17:55:41 2001
> +++ linux/Documentation/filesystems/devfs/ChangeLog Mon Jul 30 19:13:00
2001
> @@ -1675,3 +1675,13 @@
> - Fixed number leak for /dev/cdroms/cdrom%d
>
> - Fixed number leak for /dev/discs/disc%d
>
+===========================================================================
====
> +Changes for patch v183
> +
> +- Fixed bug in <devfs_setup> which could hang boot process
>
+===========================================================================
====
> +Changes for patch v184
> +
> +- Support large numbers of SCSI discs (~2144)
> +
> +- Documentation typo fix for fs/devfs/util.c
> diff -urN linux-2.4.7/drivers/scsi/Config.in linux/drivers/scsi/Config.in
> --- linux-2.4.7/drivers/scsi/Config.in Thu Jul 5 14:28:16 2001
> +++ linux/drivers/scsi/Config.in Mon Jul 23 01:19:47 2001
> @@ -3,7 +3,8 @@
> dep_tristate ' SCSI disk support' CONFIG_BLK_DEV_SD $CONFIG_SCSI
>
> if [ "$CONFIG_BLK_DEV_SD" != "n" ]; then
> - int 'Maximum number of SCSI disks that can be loaded as modules'
CONFIG_SD_EXTRA_DEVS 40
> + bool ' Many (~2144) SCSI discs support (requires devfs)'
CONFIG_SD_MANY
> + int ' Maximum number of SCSI disks that can be loaded as modules'
CONFIG_SD_EXTRA_DEVS 40
> fi
>
> dep_tristate ' SCSI tape support' CONFIG_CHR_DEV_ST $CONFIG_SCSI
> diff -urN linux-2.4.7/drivers/scsi/hosts.h linux/drivers/scsi/hosts.h
> --- linux-2.4.7/drivers/scsi/hosts.h Fri Jul 20 15:55:46 2001
> +++ linux/drivers/scsi/hosts.h Mon Jul 30 19:20:27 2001
> @@ -506,9 +506,8 @@
> const char * tag;
> struct module * module; /* Used for loadable modules */
> unsigned char scsi_type;
> - unsigned int major;
> - unsigned int min_major; /* Minimum major in range. */
> - unsigned int max_major; /* Maximum major in range. */
> + unsigned int *majors; /* Array of majors used by driver */
> + unsigned int num_majors; /* Number of majors used by driver */
> unsigned int nr_dev; /* Number currently attached */
> unsigned int dev_noticed; /* Number of devices detected. */
> unsigned int dev_max; /* Current size of arrays */
> diff -urN linux-2.4.7/drivers/scsi/osst.c linux/drivers/scsi/osst.c
> --- linux-2.4.7/drivers/scsi/osst.c Fri Jul 20 00:18:15 2001
> +++ linux/drivers/scsi/osst.c Mon Jul 30 17:57:27 2001
> @@ -160,7 +160,6 @@
> name: "OnStream tape",
> tag: "osst",
> scsi_type: TYPE_TAPE,
> - major: OSST_MAJOR,
> detect: osst_detect,
> init: osst_init,
> attach: osst_attach,
> diff -urN linux-2.4.7/drivers/scsi/scsi_lib.c
linux/drivers/scsi/scsi_lib.c
> --- linux-2.4.7/drivers/scsi/scsi_lib.c Thu Jul 19 23:48:04 2001
> +++ linux/drivers/scsi/scsi_lib.c Mon Jul 30 17:52:35 2001
> @@ -769,25 +769,10 @@
> * Search for a block device driver that supports this
> * major.
> */
> - if (spnt->blk && spnt->major == major) {
> - return spnt;
> - }
> - /*
> - * I am still not entirely satisfied with this solution,
> - * but it is good enough for now. Disks have a number of
> - * major numbers associated with them, the primary
> - * 8, which we test above, and a secondary range of 7
> - * different consecutive major numbers. If this ever
> - * becomes insufficient, then we could add another function
> - * to the structure, and generalize this completely.
> - */
> - if( spnt->min_major != 0
> - && spnt->max_major != 0
> - && major >= spnt->min_major
> - && major <= spnt->max_major )
> - {
> - return spnt;
> - }
> + int i;
> + if (!spnt->blk || !spnt->majors) continue;
> + for (i = 0; i < spnt->num_majors; ++i)
> + if (spnt->majors[i] == major) return spnt;
> }
> return NULL;
> }
> diff -urN linux-2.4.7/drivers/scsi/sd.c linux/drivers/scsi/sd.c
> --- linux-2.4.7/drivers/scsi/sd.c Thu Jul 5 14:28:17 2001
> +++ linux/drivers/scsi/sd.c Mon Jul 30 20:10:58 2001
> @@ -28,6 +28,8 @@
> *
> * Modified by Alex Davis <[email protected]>
> * Fix problem where removable media could be ejected after
sd_open.
> + *
> + * Modified by Richard Gooch [email protected] to support >128
discs.
> */
>
> #include <linux/config.h>
> @@ -65,7 +67,7 @@
> * static const char RCSid[] = "$Header:";
> */
>
> -#define SD_MAJOR(i) (!(i) ? SCSI_DISK0_MAJOR : SCSI_DISK1_MAJOR-1+(i))
> +#define SD_MAJOR(i) sd_template.majors[(i)]
>
> #define SCSI_DISKS_PER_MAJOR 16
> #define SD_MAJOR_NUMBER(i) SD_MAJOR((i) >> 8)
> @@ -108,12 +110,6 @@
> name:"disk",
> tag:"sd",
> scsi_type:TYPE_DISK,
> - major:SCSI_DISK0_MAJOR,
> - /*
> - * Secondary range of majors that this driver handles.
> - */
> - min_major:SCSI_DISK1_MAJOR,
> - max_major:SCSI_DISK7_MAJOR,
> blk:1,
> detect:sd_detect,
> init:sd_init,
> @@ -123,6 +119,19 @@
> init_command:sd_init_command,
> };
>
> +#ifdef CONFIG_SD_MANY
> +static inline int sd_devnum_to_index (int devnum)
> +{
> + int i, major = MAJOR (devnum);
> +
> + for (i = 0; i < sd_template.num_majors; ++i)
> + {
> + if (sd_template.majors[i] != major) continue;
> + return (i << 4) | (MINOR (i) >> 4);
> + }
> + return -ENODEV;
> +}
> +#endif
>
> static void rw_intr(Scsi_Cmnd * SCpnt);
>
> @@ -1043,6 +1052,41 @@
> return i;
> }
>
> +static int sd_alloc_majors (void)
> +/* Allocate as many majors as required
> + */
> +{
> + int i, major;
> +
> + if ( ( sd_template.majors =
> + kmalloc (sizeof sd_template.majors * N_USED_SD_MAJORS,
> + GFP_ATOMIC) ) == NULL ) {
> + printk ("sd.c: unable to allocate major array\n");
> + return -ENOMEM;
> + }
> + sd_template.majors[0] = SCSI_DISK0_MAJOR;
> + for (i = 1; (i < N_USED_SD_MAJORS) && (i <N_SD_PREASSIGNED_MAJORS);++i)
> + sd_template.majors[i] = SCSI_DISK1_MAJOR + i - 1;
> + for (; (i >= N_SD_PREASSIGNED_MAJORS) && (i < N_USED_SD_MAJORS); ++i) {
> + if ( ( major = devfs_alloc_major (DEVFS_SPECIAL_BLK) ) < 0 )
> + break;
> + sd_template.majors[i] = major;
> + }
> + sd_template.dev_max = i * SCSI_DISKS_PER_MAJOR;
> + sd_template.num_majors = i;
> + return 0;
> +} /* End Function sd_alloc_majors */
> +
> +static void sd_dealloc_majors (void)
> +/* Deallocate all the allocated majors
> + */
> +{
> + int i;
> +
> + for (i = sd_template.num_majors - 1; i >= N_SD_PREASSIGNED_MAJORS; --i)
> + devfs_dealloc_major (DEVFS_SPECIAL_BLK, sd_template.majors[i]);
> +} /* End Function sd_dealloc_majors */
> +
> /*
> * The sd_init() function looks at all SCSI drives present, determines
> * their size, and reads partition table entries for them.
> @@ -1057,16 +1101,16 @@
> if (sd_template.dev_noticed == 0)
> return 0;
>
> - if (!rscsi_disks)
> + if (!rscsi_disks) {
> sd_template.dev_max = sd_template.dev_noticed + SD_EXTRA_DEVS;
> -
> - if (sd_template.dev_max > N_SD_MAJORS * SCSI_DISKS_PER_MAJOR)
> - sd_template.dev_max = N_SD_MAJORS * SCSI_DISKS_PER_MAJOR;
> + if ( !sd_alloc_majors() ) return 1;
> + }
>
> if (!sd_registered) {
> 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));
> + sd_dealloc_majors();
> return 1;
> }
> }
> @@ -1166,6 +1210,7 @@
> for (i = 0; i < N_USED_SD_MAJORS; i++) {
> devfs_unregister_blkdev(SD_MAJOR(i), "sd");
> }
> + sd_dealloc_majors();
> sd_registered--;
> return 1;
> }
> @@ -1373,6 +1418,7 @@
>
> scsi_unregister_module(MODULE_SCSI_DEV, &sd_template);
>
> + sd_dealloc_majors();
> for (i = 0; i < N_USED_SD_MAJORS; i++)
> devfs_unregister_blkdev(SD_MAJOR(i), "sd");
>
> diff -urN linux-2.4.7/drivers/scsi/sd.h linux/drivers/scsi/sd.h
> --- linux-2.4.7/drivers/scsi/sd.h Fri Jul 20 15:55:46 2001
> +++ linux/drivers/scsi/sd.h Mon Jul 30 20:09:12 2001
> @@ -42,10 +42,14 @@
> */
> extern kdev_t sd_find_target(void *host, int tgt);
>
> -#define N_SD_MAJORS 8
> +#define N_SD_PREASSIGNED_MAJORS 8
>
> +#ifdef CONFIG_SD_MANY
> +#define SD_PARTITION(i) ((sd_devnum_to_index((i)) << 4) | ((i)&0x0f))
> +#else
> #define SD_MAJOR_MASK (N_SD_MAJORS - 1)
> #define SD_PARTITION(i) (((MAJOR(i) & SD_MAJOR_MASK) << 8) | (MINOR(i) &
255))
> +#endif
>
> #endif
>
> diff -urN linux-2.4.7/drivers/scsi/sg.c linux/drivers/scsi/sg.c
> --- linux-2.4.7/drivers/scsi/sg.c Wed Jul 4 18:39:28 2001
> +++ linux/drivers/scsi/sg.c Mon Jul 30 17:57:52 2001
> @@ -123,7 +123,6 @@
> {
> tag:"sg",
> scsi_type:0xff,
> - major:SCSI_GENERIC_MAJOR,
> detect:sg_detect,
> init:sg_init,
> finish:sg_finish,
> diff -urN linux-2.4.7/drivers/scsi/sr.c linux/drivers/scsi/sr.c
> --- linux-2.4.7/drivers/scsi/sr.c Thu Jul 5 14:28:17 2001
> +++ linux/drivers/scsi/sr.c Mon Jul 30 17:59:33 2001
> @@ -69,12 +69,15 @@
>
> static int sr_init_command(Scsi_Cmnd *);
>
> +static unsigned int sr_major = SCSI_CDROM_MAJOR;
> +
> static struct Scsi_Device_Template sr_template =
> {
> name:"cdrom",
> tag:"sr",
> scsi_type:TYPE_ROM,
> - major:SCSI_CDROM_MAJOR,
> + majors:&sr_major,
> + num_majors:1,
> blk:1,
> detect:sr_detect,
> init:sr_init,
> diff -urN linux-2.4.7/drivers/scsi/st.c linux/drivers/scsi/st.c
> --- linux-2.4.7/drivers/scsi/st.c Fri Jul 20 00:16:32 2001
> +++ linux/drivers/scsi/st.c Mon Jul 30 17:58:22 2001
> @@ -160,7 +160,6 @@
> name:"tape",
> tag:"st",
> scsi_type:TYPE_TAPE,
> - major:SCSI_TAPE_MAJOR,
> detect:st_detect,
> init:st_init,
> attach:st_attach,
> diff -urN linux-2.4.7/fs/devfs/base.c linux/fs/devfs/base.c
> --- linux-2.4.7/fs/devfs/base.c Wed Jul 11 17:55:41 2001
> +++ linux/fs/devfs/base.c Mon Jul 30 19:10:41 2001
> @@ -511,6 +511,9 @@
> Removed broken devnum allocation and use <devfs_alloc_devnum>.
> Fixed old devnum leak by calling new <devfs_dealloc_devnum>.
> v0.107
> + 20010712 Richard Gooch <[email protected]>
> + Fixed bug in <devfs_setup> which could hang boot process.
> + v0.108
> */
> #include <linux/types.h>
> #include <linux/errno.h>
> @@ -543,7 +546,7 @@
> #include <asm/bitops.h>
> #include <asm/atomic.h>
>
> -#define DEVFS_VERSION "0.107 (20010709)"
> +#define DEVFS_VERSION "0.108 (20010712)"
>
> #define DEVFS_NAME "devfs"
>
> @@ -1342,12 +1345,12 @@
> return NULL;
> }
> }
> - de->u.fcb.autogen = 0;
> + de->u.fcb.autogen = FALSE;
> if ( S_ISCHR (mode) || S_ISBLK (mode) )
> {
> de->u.fcb.u.device.major = major;
> de->u.fcb.u.device.minor = minor;
> - de->u.fcb.autogen = (devnum == NODEV) ? 0 : 1;
> + de->u.fcb.autogen = (devnum == NODEV) ? FALSE : TRUE;
> }
> else if ( S_ISREG (mode) ) de->u.fcb.u.file.size = 0;
> else
> @@ -1418,7 +1421,7 @@
> MKDEV (de->u.fcb.u.device.major,
> de->u.fcb.u.device.minor) );
> }
> - de->u.fcb.autogen = 0;
> + de->u.fcb.autogen = FALSE;
> return;
> }
> if (S_ISLNK (de->mode) && de->registered)
> @@ -2063,6 +2066,7 @@
> {"show", OPTION_SHOW, &boot_options},
> {"only", OPTION_ONLY, &boot_options},
> {"mount", OPTION_MOUNT, &boot_options},
> + {NULL, 0, NULL}
> };
>
> while ( (*str != '\0') && !isspace (*str) )
> @@ -2074,7 +2078,7 @@
> invert = 1;
> str += 2;
> }
> - for (i = 0; i < sizeof (devfs_options_tab); i++)
> + for (i = 0; devfs_options_tab[i].name != NULL; i++)
> {
> int len = strlen (devfs_options_tab[i].name);
>
> diff -urN linux-2.4.7/fs/devfs/util.c linux/fs/devfs/util.c
> --- linux-2.4.7/fs/devfs/util.c Wed Jul 11 17:55:41 2001
> +++ linux/fs/devfs/util.c Mon Jul 30 18:28:12 2001
> @@ -39,6 +39,8 @@
> Created <devfs_*alloc_major> and <devfs_*alloc_devnum>.
> 20010710 Richard Gooch <[email protected]>
> Created <devfs_*alloc_unique_number>.
> + 20010730 Richard Gooch <[email protected]>
> + Documentation typo fix.
> */
> #include <linux/module.h>
> #include <linux/init.h>
> @@ -214,7 +216,7 @@
>
> /**
> * devfs_alloc_major - Allocate a major number.
> - * @type: The type of the major (DEVFS_SPECIAL_CHR or
DEVFS_SPECIAL_BLOCK)
> + * @type: The type of the major (DEVFS_SPECIAL_CHR or DEVFS_SPECIAL_BLK)
>
> * Returns the allocated major, else -1 if none are available.
> * This routine is thread safe and does not block.
> @@ -238,7 +240,7 @@
>
> /**
> * devfs_dealloc_major - Deallocate a major number.
> - * @type: The type of the major (DEVFS_SPECIAL_CHR or
DEVFS_SPECIAL_BLOCK)
> + * @type: The type of the major (DEVFS_SPECIAL_CHR or DEVFS_SPECIAL_BLK)
> * @major: The major number.
> * This routine is thread safe and does not block.
> */
> @@ -282,7 +284,7 @@
>
> /**
> * devfs_alloc_devnum - Allocate a device number.
> - * @type: The type (DEVFS_SPECIAL_CHR or DEVFS_SPECIAL_BLOCK).
> + * @type: The type (DEVFS_SPECIAL_CHR or DEVFS_SPECIAL_BLK).
> *
> * Returns the allocated device number, else NODEV if none are available.
> * This routine is thread safe and may block.
> @@ -347,7 +349,7 @@
>
> /**
> * devfs_dealloc_devnum - Dellocate a device number.
> - * @type: The type (DEVFS_SPECIAL_CHR or DEVFS_SPECIAL_BLOCK).
> + * @type: The type (DEVFS_SPECIAL_CHR or DEVFS_SPECIAL_BLK).
> * @devnum: The device number.
> *
> * This routine is thread safe and does not block.
> diff -urN linux-2.4.7/include/linux/blk.h linux/include/linux/blk.h
> --- linux-2.4.7/include/linux/blk.h Mon Jul 30 19:20:01 2001
> +++ linux/include/linux/blk.h Mon Jul 30 20:05:18 2001
> @@ -144,7 +144,11 @@
>
> #define DEVICE_NAME "scsidisk"
> #define TIMEOUT_VALUE (2*HZ)
> +#ifdef CONFIG_SD_MANY
> +#define DEVICE_NR(device) sd_devnum_to_index((device))
> +#else
> #define DEVICE_NR(device) (((MAJOR(device) & SD_MAJOR_MASK) << (8 - 4)) +
(MINOR(device) >> 4))
> +#endif
>
> /* Kludge to use the same number for both char and block major numbers */
> #elif (MAJOR_NR == MD_MAJOR) && defined(MD_DRIVER)
> -
> To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
> the body of a message to [email protected]
>

2001-07-31 20:00:16

by Mike Anderson

[permalink] [raw]
Subject: Re: [RFT] Support for ~2144 SCSI discs

Richard Gooch [[email protected]] wrote:
> Jeremy Higdon writes:
> > With the sard patch and a 64 bit system, you start having
> > trouble at around 103 configured disks, because of the following
>
> So even without my patch, sard doesn't support the previous limit of
> 128 devices.
>
> > line in sd_init() (sd.c), because kmalloc doesn't like allocating
> > large chunks of memory:
> >
> > sd = kmalloc((sd_template.dev_max << 4) *
> > sizeof(struct hd_struct),
> > GFP_ATOMIC);
> >
> > Without sard, you'd have problems past 512 disks.
>
> Yes, when I was coding up the patch I noticed the use of GFP_ATOMIC in
> the allocation calls. I have two questions:
> - can we use GFP_KERNEL instead (why use GFP_ATOMIC)
> - can we switch to vmalloc() instead of kmalloc()?

In previous experiments trying to connect up to 512 devices we switched to
vmalloc because the static nature of sd.c's allocation exceeds 128k which
I assumed was the max for kmalloc YMMV.

> Regards,
>
> Richard....
> Permanent: [email protected]
> Current: [email protected]
> -
> To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
> the body of a message to [email protected]

-Mike
--
Michael Anderson
[email protected]

2001-07-31 22:53:45

by Mike Panetta

[permalink] [raw]
Subject: Re: [RFT] Support for ~2144 SCSI discs

Any maybe target mode? That would be nice to
have :) Or is it already here?

Mike

On Tue, Jul 31, 2001 at 10:10:59AM -0400, Eric Youngdale wrote:
>
> FYI - At some point in the 2.5 series I would like to do some serious
> surgery on the sd datastructures - this will mainly remove load order
> dependencies and eliminate the need for CONFIG_SD_EXTRA. I believe that
> some of the work that Jens has already started on the blk device layer will
> make support for very large numbers of disks much easier.
>
> -Eric
>
> ----- Original Message -----
> From: "Richard Gooch" <[email protected]>
> To: <[email protected]>; <[email protected]>
> Cc: <[email protected]>
> Sent: Monday, July 30, 2001 8:30 PM
> Subject: [RFT] Support for ~2144 SCSI discs
>
>
> > Hi, all. Below is a patch that adds support for large numbers of
> > SCSI discs (approximately 2144). I'd like people to try this out. I'm
> > not doing my normal devfs-patch-v??? thing because this is completely
> > untested (I'm away from my SCSI boxes), and I don't want to put a
> > possibly FS-corrupting patch on my ftp archive. The code does compile
> > and link, though.
> >
> > There are 3 cases I'd like to have tested:
> > - people with 1 to 16 SCSI discs
> > - people with 17 to 128 SCSI discs
> > - people with >128 SCSI discs
> >
> > because each of these exercises a slightly different setup path.
> > Please send success or failure reports to me.
> >
> > REMINDER: be careful with this patch. It could corrupt your FS.
> >
> > Regards,
> >
> > Richard....
> > Permanent: [email protected]
> > Current: [email protected]
> >
> > diff -urN linux-2.4.7/Documentation/Configure.help
> linux/Documentation/Configure.help
> > --- linux-2.4.7/Documentation/Configure.help Thu Jul 19 20:48:15 2001
> > +++ linux/Documentation/Configure.help Mon Jul 23 01:19:24 2001
> > @@ -5410,6 +5410,17 @@
> > located on a SCSI disk. In this case, do not compile the driver for
> > your SCSI host adapter (below) as a module either.
> >
> > +Many SCSI Discs support
> > +CONFIG_SD_MANY
> > + This allows you to support a very large number of SCSI discs
> > + (approximately 2144). You will also need to set CONFIG_DEVFS_FS=y
> > + later. This option may consume all unassigned block majors
> > + (i.e. those which do not have an allocation in
> > + Documentation/devices.txt). Enabling this will consume a few extra
> > + kilobytes of kernel memory.
> > +
> > + Unless you have a large storage array, say N.
> > +
> > Extra SCSI Disks
> > CONFIG_SD_EXTRA_DEVS
> > This controls the amount of additional space allocated in tables for
> > diff -urN linux-2.4.7/Documentation/filesystems/devfs/ChangeLog
> linux/Documentation/filesystems/devfs/ChangeLog
> > --- linux-2.4.7/Documentation/filesystems/devfs/ChangeLog Wed Jul 11
> 17:55:41 2001
> > +++ linux/Documentation/filesystems/devfs/ChangeLog Mon Jul 30 19:13:00
> 2001
> > @@ -1675,3 +1675,13 @@
> > - Fixed number leak for /dev/cdroms/cdrom%d
> >
> > - Fixed number leak for /dev/discs/disc%d
> >
> +===========================================================================
> ====
> > +Changes for patch v183
> > +
> > +- Fixed bug in <devfs_setup> which could hang boot process
> >
> +===========================================================================
> ====
> > +Changes for patch v184
> > +
> > +- Support large numbers of SCSI discs (~2144)
> > +
> > +- Documentation typo fix for fs/devfs/util.c
> > diff -urN linux-2.4.7/drivers/scsi/Config.in linux/drivers/scsi/Config.in
> > --- linux-2.4.7/drivers/scsi/Config.in Thu Jul 5 14:28:16 2001
> > +++ linux/drivers/scsi/Config.in Mon Jul 23 01:19:47 2001
> > @@ -3,7 +3,8 @@
> > dep_tristate ' SCSI disk support' CONFIG_BLK_DEV_SD $CONFIG_SCSI
> >
> > if [ "$CONFIG_BLK_DEV_SD" != "n" ]; then
> > - int 'Maximum number of SCSI disks that can be loaded as modules'
> CONFIG_SD_EXTRA_DEVS 40
> > + bool ' Many (~2144) SCSI discs support (requires devfs)'
> CONFIG_SD_MANY
> > + int ' Maximum number of SCSI disks that can be loaded as modules'
> CONFIG_SD_EXTRA_DEVS 40
> > fi
> >
> > dep_tristate ' SCSI tape support' CONFIG_CHR_DEV_ST $CONFIG_SCSI
> > diff -urN linux-2.4.7/drivers/scsi/hosts.h linux/drivers/scsi/hosts.h
> > --- linux-2.4.7/drivers/scsi/hosts.h Fri Jul 20 15:55:46 2001
> > +++ linux/drivers/scsi/hosts.h Mon Jul 30 19:20:27 2001
> > @@ -506,9 +506,8 @@
> > const char * tag;
> > struct module * module; /* Used for loadable modules */
> > unsigned char scsi_type;
> > - unsigned int major;
> > - unsigned int min_major; /* Minimum major in range. */
> > - unsigned int max_major; /* Maximum major in range. */
> > + unsigned int *majors; /* Array of majors used by driver */
> > + unsigned int num_majors; /* Number of majors used by driver */
> > unsigned int nr_dev; /* Number currently attached */
> > unsigned int dev_noticed; /* Number of devices detected. */
> > unsigned int dev_max; /* Current size of arrays */
> > diff -urN linux-2.4.7/drivers/scsi/osst.c linux/drivers/scsi/osst.c
> > --- linux-2.4.7/drivers/scsi/osst.c Fri Jul 20 00:18:15 2001
> > +++ linux/drivers/scsi/osst.c Mon Jul 30 17:57:27 2001
> > @@ -160,7 +160,6 @@
> > name: "OnStream tape",
> > tag: "osst",
> > scsi_type: TYPE_TAPE,
> > - major: OSST_MAJOR,
> > detect: osst_detect,
> > init: osst_init,
> > attach: osst_attach,
> > diff -urN linux-2.4.7/drivers/scsi/scsi_lib.c
> linux/drivers/scsi/scsi_lib.c
> > --- linux-2.4.7/drivers/scsi/scsi_lib.c Thu Jul 19 23:48:04 2001
> > +++ linux/drivers/scsi/scsi_lib.c Mon Jul 30 17:52:35 2001
> > @@ -769,25 +769,10 @@
> > * Search for a block device driver that supports this
> > * major.
> > */
> > - if (spnt->blk && spnt->major == major) {
> > - return spnt;
> > - }
> > - /*
> > - * I am still not entirely satisfied with this solution,
> > - * but it is good enough for now. Disks have a number of
> > - * major numbers associated with them, the primary
> > - * 8, which we test above, and a secondary range of 7
> > - * different consecutive major numbers. If this ever
> > - * becomes insufficient, then we could add another function
> > - * to the structure, and generalize this completely.
> > - */
> > - if( spnt->min_major != 0
> > - && spnt->max_major != 0
> > - && major >= spnt->min_major
> > - && major <= spnt->max_major )
> > - {
> > - return spnt;
> > - }
> > + int i;
> > + if (!spnt->blk || !spnt->majors) continue;
> > + for (i = 0; i < spnt->num_majors; ++i)
> > + if (spnt->majors[i] == major) return spnt;
> > }
> > return NULL;
> > }
> > diff -urN linux-2.4.7/drivers/scsi/sd.c linux/drivers/scsi/sd.c
> > --- linux-2.4.7/drivers/scsi/sd.c Thu Jul 5 14:28:17 2001
> > +++ linux/drivers/scsi/sd.c Mon Jul 30 20:10:58 2001
> > @@ -28,6 +28,8 @@
> > *
> > * Modified by Alex Davis <[email protected]>
> > * Fix problem where removable media could be ejected after
> sd_open.
> > + *
> > + * Modified by Richard Gooch [email protected] to support >128
> discs.
> > */
> >
> > #include <linux/config.h>
> > @@ -65,7 +67,7 @@
> > * static const char RCSid[] = "$Header:";
> > */
> >
> > -#define SD_MAJOR(i) (!(i) ? SCSI_DISK0_MAJOR : SCSI_DISK1_MAJOR-1+(i))
> > +#define SD_MAJOR(i) sd_template.majors[(i)]
> >
> > #define SCSI_DISKS_PER_MAJOR 16
> > #define SD_MAJOR_NUMBER(i) SD_MAJOR((i) >> 8)
> > @@ -108,12 +110,6 @@
> > name:"disk",
> > tag:"sd",
> > scsi_type:TYPE_DISK,
> > - major:SCSI_DISK0_MAJOR,
> > - /*
> > - * Secondary range of majors that this driver handles.
> > - */
> > - min_major:SCSI_DISK1_MAJOR,
> > - max_major:SCSI_DISK7_MAJOR,
> > blk:1,
> > detect:sd_detect,
> > init:sd_init,
> > @@ -123,6 +119,19 @@
> > init_command:sd_init_command,
> > };
> >
> > +#ifdef CONFIG_SD_MANY
> > +static inline int sd_devnum_to_index (int devnum)
> > +{
> > + int i, major = MAJOR (devnum);
> > +
> > + for (i = 0; i < sd_template.num_majors; ++i)
> > + {
> > + if (sd_template.majors[i] != major) continue;
> > + return (i << 4) | (MINOR (i) >> 4);
> > + }
> > + return -ENODEV;
> > +}
> > +#endif
> >
> > static void rw_intr(Scsi_Cmnd * SCpnt);
> >
> > @@ -1043,6 +1052,41 @@
> > return i;
> > }
> >
> > +static int sd_alloc_majors (void)
> > +/* Allocate as many majors as required
> > + */
> > +{
> > + int i, major;
> > +
> > + if ( ( sd_template.majors =
> > + kmalloc (sizeof sd_template.majors * N_USED_SD_MAJORS,
> > + GFP_ATOMIC) ) == NULL ) {
> > + printk ("sd.c: unable to allocate major array\n");
> > + return -ENOMEM;
> > + }
> > + sd_template.majors[0] = SCSI_DISK0_MAJOR;
> > + for (i = 1; (i < N_USED_SD_MAJORS) && (i <N_SD_PREASSIGNED_MAJORS);++i)
> > + sd_template.majors[i] = SCSI_DISK1_MAJOR + i - 1;
> > + for (; (i >= N_SD_PREASSIGNED_MAJORS) && (i < N_USED_SD_MAJORS); ++i) {
> > + if ( ( major = devfs_alloc_major (DEVFS_SPECIAL_BLK) ) < 0 )
> > + break;
> > + sd_template.majors[i] = major;
> > + }
> > + sd_template.dev_max = i * SCSI_DISKS_PER_MAJOR;
> > + sd_template.num_majors = i;
> > + return 0;
> > +} /* End Function sd_alloc_majors */
> > +
> > +static void sd_dealloc_majors (void)
> > +/* Deallocate all the allocated majors
> > + */
> > +{
> > + int i;
> > +
> > + for (i = sd_template.num_majors - 1; i >= N_SD_PREASSIGNED_MAJORS; --i)
> > + devfs_dealloc_major (DEVFS_SPECIAL_BLK, sd_template.majors[i]);
> > +} /* End Function sd_dealloc_majors */
> > +
> > /*
> > * The sd_init() function looks at all SCSI drives present, determines
> > * their size, and reads partition table entries for them.
> > @@ -1057,16 +1101,16 @@
> > if (sd_template.dev_noticed == 0)
> > return 0;
> >
> > - if (!rscsi_disks)
> > + if (!rscsi_disks) {
> > sd_template.dev_max = sd_template.dev_noticed + SD_EXTRA_DEVS;
> > -
> > - if (sd_template.dev_max > N_SD_MAJORS * SCSI_DISKS_PER_MAJOR)
> > - sd_template.dev_max = N_SD_MAJORS * SCSI_DISKS_PER_MAJOR;
> > + if ( !sd_alloc_majors() ) return 1;
> > + }
> >
> > if (!sd_registered) {
> > 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));
> > + sd_dealloc_majors();
> > return 1;
> > }
> > }
> > @@ -1166,6 +1210,7 @@
> > for (i = 0; i < N_USED_SD_MAJORS; i++) {
> > devfs_unregister_blkdev(SD_MAJOR(i), "sd");
> > }
> > + sd_dealloc_majors();
> > sd_registered--;
> > return 1;
> > }
> > @@ -1373,6 +1418,7 @@
> >
> > scsi_unregister_module(MODULE_SCSI_DEV, &sd_template);
> >
> > + sd_dealloc_majors();
> > for (i = 0; i < N_USED_SD_MAJORS; i++)
> > devfs_unregister_blkdev(SD_MAJOR(i), "sd");
> >
> > diff -urN linux-2.4.7/drivers/scsi/sd.h linux/drivers/scsi/sd.h
> > --- linux-2.4.7/drivers/scsi/sd.h Fri Jul 20 15:55:46 2001
> > +++ linux/drivers/scsi/sd.h Mon Jul 30 20:09:12 2001
> > @@ -42,10 +42,14 @@
> > */
> > extern kdev_t sd_find_target(void *host, int tgt);
> >
> > -#define N_SD_MAJORS 8
> > +#define N_SD_PREASSIGNED_MAJORS 8
> >
> > +#ifdef CONFIG_SD_MANY
> > +#define SD_PARTITION(i) ((sd_devnum_to_index((i)) << 4) | ((i)&0x0f))
> > +#else
> > #define SD_MAJOR_MASK (N_SD_MAJORS - 1)
> > #define SD_PARTITION(i) (((MAJOR(i) & SD_MAJOR_MASK) << 8) | (MINOR(i) &
> 255))
> > +#endif
> >
> > #endif
> >
> > diff -urN linux-2.4.7/drivers/scsi/sg.c linux/drivers/scsi/sg.c
> > --- linux-2.4.7/drivers/scsi/sg.c Wed Jul 4 18:39:28 2001
> > +++ linux/drivers/scsi/sg.c Mon Jul 30 17:57:52 2001
> > @@ -123,7 +123,6 @@
> > {
> > tag:"sg",
> > scsi_type:0xff,
> > - major:SCSI_GENERIC_MAJOR,
> > detect:sg_detect,
> > init:sg_init,
> > finish:sg_finish,
> > diff -urN linux-2.4.7/drivers/scsi/sr.c linux/drivers/scsi/sr.c
> > --- linux-2.4.7/drivers/scsi/sr.c Thu Jul 5 14:28:17 2001
> > +++ linux/drivers/scsi/sr.c Mon Jul 30 17:59:33 2001
> > @@ -69,12 +69,15 @@
> >
> > static int sr_init_command(Scsi_Cmnd *);
> >
> > +static unsigned int sr_major = SCSI_CDROM_MAJOR;
> > +
> > static struct Scsi_Device_Template sr_template =
> > {
> > name:"cdrom",
> > tag:"sr",
> > scsi_type:TYPE_ROM,
> > - major:SCSI_CDROM_MAJOR,
> > + majors:&sr_major,
> > + num_majors:1,
> > blk:1,
> > detect:sr_detect,
> > init:sr_init,
> > diff -urN linux-2.4.7/drivers/scsi/st.c linux/drivers/scsi/st.c
> > --- linux-2.4.7/drivers/scsi/st.c Fri Jul 20 00:16:32 2001
> > +++ linux/drivers/scsi/st.c Mon Jul 30 17:58:22 2001
> > @@ -160,7 +160,6 @@
> > name:"tape",
> > tag:"st",
> > scsi_type:TYPE_TAPE,
> > - major:SCSI_TAPE_MAJOR,
> > detect:st_detect,
> > init:st_init,
> > attach:st_attach,
> > diff -urN linux-2.4.7/fs/devfs/base.c linux/fs/devfs/base.c
> > --- linux-2.4.7/fs/devfs/base.c Wed Jul 11 17:55:41 2001
> > +++ linux/fs/devfs/base.c Mon Jul 30 19:10:41 2001
> > @@ -511,6 +511,9 @@
> > Removed broken devnum allocation and use <devfs_alloc_devnum>.
> > Fixed old devnum leak by calling new <devfs_dealloc_devnum>.
> > v0.107
> > + 20010712 Richard Gooch <[email protected]>
> > + Fixed bug in <devfs_setup> which could hang boot process.
> > + v0.108
> > */
> > #include <linux/types.h>
> > #include <linux/errno.h>
> > @@ -543,7 +546,7 @@
> > #include <asm/bitops.h>
> > #include <asm/atomic.h>
> >
> > -#define DEVFS_VERSION "0.107 (20010709)"
> > +#define DEVFS_VERSION "0.108 (20010712)"
> >
> > #define DEVFS_NAME "devfs"
> >
> > @@ -1342,12 +1345,12 @@
> > return NULL;
> > }
> > }
> > - de->u.fcb.autogen = 0;
> > + de->u.fcb.autogen = FALSE;
> > if ( S_ISCHR (mode) || S_ISBLK (mode) )
> > {
> > de->u.fcb.u.device.major = major;
> > de->u.fcb.u.device.minor = minor;
> > - de->u.fcb.autogen = (devnum == NODEV) ? 0 : 1;
> > + de->u.fcb.autogen = (devnum == NODEV) ? FALSE : TRUE;
> > }
> > else if ( S_ISREG (mode) ) de->u.fcb.u.file.size = 0;
> > else
> > @@ -1418,7 +1421,7 @@
> > MKDEV (de->u.fcb.u.device.major,
> > de->u.fcb.u.device.minor) );
> > }
> > - de->u.fcb.autogen = 0;
> > + de->u.fcb.autogen = FALSE;
> > return;
> > }
> > if (S_ISLNK (de->mode) && de->registered)
> > @@ -2063,6 +2066,7 @@
> > {"show", OPTION_SHOW, &boot_options},
> > {"only", OPTION_ONLY, &boot_options},
> > {"mount", OPTION_MOUNT, &boot_options},
> > + {NULL, 0, NULL}
> > };
> >
> > while ( (*str != '\0') && !isspace (*str) )
> > @@ -2074,7 +2078,7 @@
> > invert = 1;
> > str += 2;
> > }
> > - for (i = 0; i < sizeof (devfs_options_tab); i++)
> > + for (i = 0; devfs_options_tab[i].name != NULL; i++)
> > {
> > int len = strlen (devfs_options_tab[i].name);
> >
> > diff -urN linux-2.4.7/fs/devfs/util.c linux/fs/devfs/util.c
> > --- linux-2.4.7/fs/devfs/util.c Wed Jul 11 17:55:41 2001
> > +++ linux/fs/devfs/util.c Mon Jul 30 18:28:12 2001
> > @@ -39,6 +39,8 @@
> > Created <devfs_*alloc_major> and <devfs_*alloc_devnum>.
> > 20010710 Richard Gooch <[email protected]>
> > Created <devfs_*alloc_unique_number>.
> > + 20010730 Richard Gooch <[email protected]>
> > + Documentation typo fix.
> > */
> > #include <linux/module.h>
> > #include <linux/init.h>
> > @@ -214,7 +216,7 @@
> >
> > /**
> > * devfs_alloc_major - Allocate a major number.
> > - * @type: The type of the major (DEVFS_SPECIAL_CHR or
> DEVFS_SPECIAL_BLOCK)
> > + * @type: The type of the major (DEVFS_SPECIAL_CHR or DEVFS_SPECIAL_BLK)
> >
> > * Returns the allocated major, else -1 if none are available.
> > * This routine is thread safe and does not block.
> > @@ -238,7 +240,7 @@
> >
> > /**
> > * devfs_dealloc_major - Deallocate a major number.
> > - * @type: The type of the major (DEVFS_SPECIAL_CHR or
> DEVFS_SPECIAL_BLOCK)
> > + * @type: The type of the major (DEVFS_SPECIAL_CHR or DEVFS_SPECIAL_BLK)
> > * @major: The major number.
> > * This routine is thread safe and does not block.
> > */
> > @@ -282,7 +284,7 @@
> >
> > /**
> > * devfs_alloc_devnum - Allocate a device number.
> > - * @type: The type (DEVFS_SPECIAL_CHR or DEVFS_SPECIAL_BLOCK).
> > + * @type: The type (DEVFS_SPECIAL_CHR or DEVFS_SPECIAL_BLK).
> > *
> > * Returns the allocated device number, else NODEV if none are available.
> > * This routine is thread safe and may block.
> > @@ -347,7 +349,7 @@
> >
> > /**
> > * devfs_dealloc_devnum - Dellocate a device number.
> > - * @type: The type (DEVFS_SPECIAL_CHR or DEVFS_SPECIAL_BLOCK).
> > + * @type: The type (DEVFS_SPECIAL_CHR or DEVFS_SPECIAL_BLK).
> > * @devnum: The device number.
> > *
> > * This routine is thread safe and does not block.
> > diff -urN linux-2.4.7/include/linux/blk.h linux/include/linux/blk.h
> > --- linux-2.4.7/include/linux/blk.h Mon Jul 30 19:20:01 2001
> > +++ linux/include/linux/blk.h Mon Jul 30 20:05:18 2001
> > @@ -144,7 +144,11 @@
> >
> > #define DEVICE_NAME "scsidisk"
> > #define TIMEOUT_VALUE (2*HZ)
> > +#ifdef CONFIG_SD_MANY
> > +#define DEVICE_NR(device) sd_devnum_to_index((device))
> > +#else
> > #define DEVICE_NR(device) (((MAJOR(device) & SD_MAJOR_MASK) << (8 - 4)) +
> (MINOR(device) >> 4))
> > +#endif
> >
> > /* Kludge to use the same number for both char and block major numbers */
> > #elif (MAJOR_NR == MD_MAJOR) && defined(MD_DRIVER)
> > -
> > To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
> > the body of a message to [email protected]
> >
>
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/

--

2001-08-01 00:40:13

by Richard Gooch

[permalink] [raw]
Subject: Re: [RFT] Support for ~2144 SCSI discs

Mike Panetta writes:
> Any maybe target mode? That would be nice to
> have :) Or is it already here?

Well, I haven't done that. I haven't looked for it myself. I don't
have any plans for that.

> > > diff -urN linux-2.4.7/Documentation/Configure.help

BTW: next time please don't quote the patch. No need to chew extra
bandwidth.

Regards,

Richard....
Permanent: [email protected]
Current: [email protected]

2001-08-01 00:49:05

by Richard Gooch

[permalink] [raw]
Subject: Re: [RFT] Support for ~2144 SCSI discs

Mike Anderson writes:
> In previous experiments trying to connect up to 512 devices we
> switched to vmalloc because the static nature of sd.c's allocation
> exceeds 128k which I assumed was the max for kmalloc YMMV.

Yes, I figure on switching to vmalloc() and putting in an
in_interrupt() test in sd_init() to make sure the vmalloc() is safe.

Eric: do you happen to know why there are these GFP_ATOMIC flags?
To my knowledge, nothing calls sd_init() outside of process context.

Regards,

Richard....
Permanent: [email protected]
Current: [email protected]

2001-08-01 01:08:54

by Douglas Gilbert

[permalink] [raw]
Subject: Re: [RFT] Support for ~2144 SCSI discs

Richard Gooch wrote:
>
> Mike Anderson writes:
> > In previous experiments trying to connect up to 512 devices we
> > switched to vmalloc because the static nature of sd.c's allocation
> > exceeds 128k which I assumed was the max for kmalloc YMMV.
>
> Yes, I figure on switching to vmalloc() and putting in an
> in_interrupt() test in sd_init() to make sure the vmalloc() is safe.
>
> Eric: do you happen to know why there are these GFP_ATOMIC flags?
> To my knowledge, nothing calls sd_init() outside of process context.

Richard,
I've seen GFP_KERNEL take 10 minutes in lk 2.4.6 . The
mm gets tweaked pretty often so it is difficult to know
exactly how it will react when memory is tight. A time
bound would be useful on GFP_KERNEL.

<opinion> It is best to find out quickly there is
not enough memory and have some alternate strategy
to cope with that problem. GFP_KERNEL in its current
form should be taken out and shot. </opinion>

Doug Gilbert