Commit d0f6f938 authored by James Bottomley's avatar James Bottomley Committed by James Bottomley

sg update to 20040516

From: Douglas Gilbert <dougg@torque.net>

Here are some further refinements to this patch with help
from Pat Mansfield:
     - replace vmalloc() with kmalloc(,GFP_KERNEL)
     - bump max sg devices from 8192 to 32768

Tested to 16k devices (and 8k devices on a box with 512MB
ram), Patch is against lk 2.6.6 (or 2.6.6-bk1).
Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent 963617c0
...@@ -42,7 +42,6 @@ static int sg_version_num = 30531; /* 2 digits for each component */ ...@@ -42,7 +42,6 @@ static int sg_version_num = 30531; /* 2 digits for each component */
#include <linux/fcntl.h> #include <linux/fcntl.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/poll.h> #include <linux/poll.h>
#include <linux/vmalloc.h>
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
#include <linux/moduleparam.h> #include <linux/moduleparam.h>
#include <linux/devfs_fs_kernel.h> #include <linux/devfs_fs_kernel.h>
...@@ -60,7 +59,7 @@ static int sg_version_num = 30531; /* 2 digits for each component */ ...@@ -60,7 +59,7 @@ static int sg_version_num = 30531; /* 2 digits for each component */
#ifdef CONFIG_SCSI_PROC_FS #ifdef CONFIG_SCSI_PROC_FS
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
static char *sg_version_date = "20040513"; static char *sg_version_date = "20040516";
static int sg_proc_init(void); static int sg_proc_init(void);
static void sg_proc_cleanup(void); static void sg_proc_cleanup(void);
...@@ -73,7 +72,7 @@ static void sg_proc_cleanup(void); ...@@ -73,7 +72,7 @@ static void sg_proc_cleanup(void);
#define SG_ALLOW_DIO_DEF 0 #define SG_ALLOW_DIO_DEF 0
#define SG_ALLOW_DIO_CODE /* compile out by commenting this define */ #define SG_ALLOW_DIO_CODE /* compile out by commenting this define */
#define SG_MAX_DEVS 8192 #define SG_MAX_DEVS 32768
/* /*
* Suppose you want to calculate the formula muldiv(x,m,d)=int(x * m / d) * Suppose you want to calculate the formula muldiv(x,m,d)=int(x * m / d)
...@@ -1330,9 +1329,11 @@ static int sg_alloc(struct gendisk *disk, struct scsi_device *scsidp) ...@@ -1330,9 +1329,11 @@ static int sg_alloc(struct gendisk *disk, struct scsi_device *scsidp)
void *old_sg_dev_arr = NULL; void *old_sg_dev_arr = NULL;
int k, error; int k, error;
sdp = vmalloc(sizeof(Sg_device)); sdp = kmalloc(sizeof(Sg_device), GFP_KERNEL);
if (!sdp) if (!sdp) {
printk(KERN_WARNING "kmalloc Sg_device failure\n");
return -ENOMEM; return -ENOMEM;
}
write_lock_irqsave(&sg_dev_arr_lock, iflags); write_lock_irqsave(&sg_dev_arr_lock, iflags);
if (unlikely(sg_nr_dev >= sg_dev_max)) { /* try to resize */ if (unlikely(sg_nr_dev >= sg_dev_max)) { /* try to resize */
...@@ -1340,7 +1341,7 @@ static int sg_alloc(struct gendisk *disk, struct scsi_device *scsidp) ...@@ -1340,7 +1341,7 @@ static int sg_alloc(struct gendisk *disk, struct scsi_device *scsidp)
int tmp_dev_max = sg_nr_dev + SG_DEV_ARR_LUMP; int tmp_dev_max = sg_nr_dev + SG_DEV_ARR_LUMP;
write_unlock_irqrestore(&sg_dev_arr_lock, iflags); write_unlock_irqrestore(&sg_dev_arr_lock, iflags);
tmp_da = vmalloc(tmp_dev_max * sizeof(Sg_device *)); tmp_da = kmalloc(tmp_dev_max * sizeof(Sg_device *), GFP_KERNEL);
if (unlikely(!tmp_da)) if (unlikely(!tmp_da))
goto expand_failed; goto expand_failed;
...@@ -1374,12 +1375,12 @@ static int sg_alloc(struct gendisk *disk, struct scsi_device *scsidp) ...@@ -1374,12 +1375,12 @@ static int sg_alloc(struct gendisk *disk, struct scsi_device *scsidp)
out: out:
if (error < 0) if (error < 0)
vfree(sdp); kfree(sdp);
vfree(old_sg_dev_arr); kfree(old_sg_dev_arr);
return error; return error;
expand_failed: expand_failed:
printk(KERN_ERR "sg_alloc: device array cannot be resized\n"); printk(KERN_WARNING "sg_alloc: device array cannot be resized\n");
error = -ENOMEM; error = -ENOMEM;
goto out; goto out;
...@@ -1403,20 +1404,26 @@ sg_add(struct class_device *cl_dev) ...@@ -1403,20 +1404,26 @@ sg_add(struct class_device *cl_dev)
int error, k; int error, k;
disk = alloc_disk(1); disk = alloc_disk(1);
if (!disk) if (!disk) {
printk(KERN_WARNING "alloc_disk failed\n");
return -ENOMEM; return -ENOMEM;
}
disk->major = SCSI_GENERIC_MAJOR; disk->major = SCSI_GENERIC_MAJOR;
error = -ENOMEM; error = -ENOMEM;
cdev = cdev_alloc(); cdev = cdev_alloc();
if (!cdev) if (!cdev) {
printk(KERN_WARNING "cdev_alloc failed\n");
goto out; goto out;
}
cdev->owner = THIS_MODULE; cdev->owner = THIS_MODULE;
cdev->ops = &sg_fops; cdev->ops = &sg_fops;
error = sg_alloc(disk, scsidp); error = sg_alloc(disk, scsidp);
if (error < 0) if (error < 0) {
printk(KERN_WARNING "sg_alloc failed\n");
goto out; goto out;
}
k = error; k = error;
sdp = sg_dev_arr[k]; sdp = sg_dev_arr[k];
...@@ -1524,7 +1531,7 @@ sg_remove(struct class_device *cl_dev) ...@@ -1524,7 +1531,7 @@ sg_remove(struct class_device *cl_dev)
put_disk(sdp->disk); put_disk(sdp->disk);
sdp->disk = NULL; sdp->disk = NULL;
if (NULL == sdp->headfp) if (NULL == sdp->headfp)
vfree((char *) sdp); kfree((char *) sdp);
} }
if (delay) if (delay)
...@@ -1589,7 +1596,7 @@ exit_sg(void) ...@@ -1589,7 +1596,7 @@ exit_sg(void)
unregister_chrdev_region(MKDEV(SCSI_GENERIC_MAJOR, 0), unregister_chrdev_region(MKDEV(SCSI_GENERIC_MAJOR, 0),
SG_MAX_DEVS); SG_MAX_DEVS);
if (sg_dev_arr != NULL) { if (sg_dev_arr != NULL) {
vfree((char *) sg_dev_arr); kfree((char *) sg_dev_arr);
sg_dev_arr = NULL; sg_dev_arr = NULL;
} }
sg_dev_max = 0; sg_dev_max = 0;
...@@ -2491,7 +2498,7 @@ sg_remove_sfp(Sg_device * sdp, Sg_fd * sfp) ...@@ -2491,7 +2498,7 @@ sg_remove_sfp(Sg_device * sdp, Sg_fd * sfp)
} }
if (k < maxd) if (k < maxd)
sg_dev_arr[k] = NULL; sg_dev_arr[k] = NULL;
vfree((char *) sdp); kfree((char *) sdp);
res = 1; res = 1;
} }
write_unlock_irqrestore(&sg_dev_arr_lock, iflags); write_unlock_irqrestore(&sg_dev_arr_lock, iflags);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment