aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDouglas Gilbert <dougg@torque.net>2006-09-20 18:20:49 -0400
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2006-09-26 12:23:15 -0400
commit6460e75a104d10458817d2f5b2fbff775bf0b43a (patch)
tree88e2a88aef94282728d1c764d02e5efa7ef7fee4
parent8aee918a1cff2a3722ce76fc6fa5abe09aa98d1b (diff)
[SCSI] sg: fixes for large page_size
This sg driver patch addresses the problem with larger page sizes reported by Brian King in this post: http://marc.theaimsgroup.com/?l=linux-scsi&m=115867718623631&w=2 Some other related matters are also addressed. Some of these prevent oopses when the SG_SCATTER_SZ or scatter_elem_sz are set to inappropriate values. The scatter_elem_sz has been tested up to 4 MB which should make the largest data transfer with one SCSI command, 32 MB less one block, achievable with a relatively small number of elements in the scatter gather list. ChangeLog: - add scatter_elem_sz boot time parameter and sysfs module parameter that is initialized to SG_SCATTER_SZ - the driver will then adjust scatter_elem_sz to be the max(given(scatter_elem_sz), PAGE_SIZE) It will also round it up, if necessary, to be a power of two - clean up sg.h header, correct bad urls and some statements that are no longer valid - make the def_reserved_size sysfs module attribute writable Signed-off-by: Douglas Gilbert <dougg@torque.net> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
-rw-r--r--drivers/scsi/sg.c53
-rw-r--r--include/scsi/sg.h61
2 files changed, 61 insertions, 53 deletions
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 34f9343ed0af..3f8b93188567 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -60,7 +60,7 @@ static int sg_version_num = 30534; /* 2 digits for each component */
60 60
61#ifdef CONFIG_SCSI_PROC_FS 61#ifdef CONFIG_SCSI_PROC_FS
62#include <linux/proc_fs.h> 62#include <linux/proc_fs.h>
63static char *sg_version_date = "20060818"; 63static char *sg_version_date = "20060920";
64 64
65static int sg_proc_init(void); 65static int sg_proc_init(void);
66static void sg_proc_cleanup(void); 66static void sg_proc_cleanup(void);
@@ -94,6 +94,9 @@ int sg_big_buff = SG_DEF_RESERVED_SIZE;
94static int def_reserved_size = -1; /* picks up init parameter */ 94static int def_reserved_size = -1; /* picks up init parameter */
95static int sg_allow_dio = SG_ALLOW_DIO_DEF; 95static int sg_allow_dio = SG_ALLOW_DIO_DEF;
96 96
97static int scatter_elem_sz = SG_SCATTER_SZ;
98static int scatter_elem_sz_prev = SG_SCATTER_SZ;
99
97#define SG_SECTOR_SZ 512 100#define SG_SECTOR_SZ 512
98#define SG_SECTOR_MSK (SG_SECTOR_SZ - 1) 101#define SG_SECTOR_MSK (SG_SECTOR_SZ - 1)
99 102
@@ -1537,11 +1540,9 @@ sg_remove(struct class_device *cl_dev, struct class_interface *cl_intf)
1537 msleep(10); /* dirty detach so delay device destruction */ 1540 msleep(10); /* dirty detach so delay device destruction */
1538} 1541}
1539 1542
1540/* Set 'perm' (4th argument) to 0 to disable module_param's definition 1543module_param_named(scatter_elem_sz, scatter_elem_sz, int, S_IRUGO | S_IWUSR);
1541 * of sysfs parameters (which module_param doesn't yet support). 1544module_param_named(def_reserved_size, def_reserved_size, int,
1542 * Sysfs parameters defined explicitly below. 1545 S_IRUGO | S_IWUSR);
1543 */
1544module_param_named(def_reserved_size, def_reserved_size, int, S_IRUGO);
1545module_param_named(allow_dio, sg_allow_dio, int, S_IRUGO | S_IWUSR); 1546module_param_named(allow_dio, sg_allow_dio, int, S_IRUGO | S_IWUSR);
1546 1547
1547MODULE_AUTHOR("Douglas Gilbert"); 1548MODULE_AUTHOR("Douglas Gilbert");
@@ -1550,6 +1551,8 @@ MODULE_LICENSE("GPL");
1550MODULE_VERSION(SG_VERSION_STR); 1551MODULE_VERSION(SG_VERSION_STR);
1551MODULE_ALIAS_CHARDEV_MAJOR(SCSI_GENERIC_MAJOR); 1552MODULE_ALIAS_CHARDEV_MAJOR(SCSI_GENERIC_MAJOR);
1552 1553
1554MODULE_PARM_DESC(scatter_elem_sz, "scatter gather element "
1555 "size (default: max(SG_SCATTER_SZ, PAGE_SIZE))");
1553MODULE_PARM_DESC(def_reserved_size, "size of buffer reserved for each fd"); 1556MODULE_PARM_DESC(def_reserved_size, "size of buffer reserved for each fd");
1554MODULE_PARM_DESC(allow_dio, "allow direct I/O (default: 0 (disallow))"); 1557MODULE_PARM_DESC(allow_dio, "allow direct I/O (default: 0 (disallow))");
1555 1558
@@ -1558,8 +1561,14 @@ init_sg(void)
1558{ 1561{
1559 int rc; 1562 int rc;
1560 1563
1564 if (scatter_elem_sz < PAGE_SIZE) {
1565 scatter_elem_sz = PAGE_SIZE;
1566 scatter_elem_sz_prev = scatter_elem_sz;
1567 }
1561 if (def_reserved_size >= 0) 1568 if (def_reserved_size >= 0)
1562 sg_big_buff = def_reserved_size; 1569 sg_big_buff = def_reserved_size;
1570 else
1571 def_reserved_size = sg_big_buff;
1563 1572
1564 rc = register_chrdev_region(MKDEV(SCSI_GENERIC_MAJOR, 0), 1573 rc = register_chrdev_region(MKDEV(SCSI_GENERIC_MAJOR, 0),
1565 SG_MAX_DEVS, "sg"); 1574 SG_MAX_DEVS, "sg");
@@ -1842,15 +1851,30 @@ sg_build_indirect(Sg_scatter_hold * schp, Sg_fd * sfp, int buff_size)
1842 if (mx_sc_elems < 0) 1851 if (mx_sc_elems < 0)
1843 return mx_sc_elems; /* most likely -ENOMEM */ 1852 return mx_sc_elems; /* most likely -ENOMEM */
1844 1853
1854 num = scatter_elem_sz;
1855 if (unlikely(num != scatter_elem_sz_prev)) {
1856 if (num < PAGE_SIZE) {
1857 scatter_elem_sz = PAGE_SIZE;
1858 scatter_elem_sz_prev = PAGE_SIZE;
1859 } else
1860 scatter_elem_sz_prev = num;
1861 }
1845 for (k = 0, sg = schp->buffer, rem_sz = blk_size; 1862 for (k = 0, sg = schp->buffer, rem_sz = blk_size;
1846 (rem_sz > 0) && (k < mx_sc_elems); 1863 (rem_sz > 0) && (k < mx_sc_elems);
1847 ++k, rem_sz -= ret_sz, ++sg) { 1864 ++k, rem_sz -= ret_sz, ++sg) {
1848 1865
1849 num = (rem_sz > SG_SCATTER_SZ) ? SG_SCATTER_SZ : rem_sz; 1866 num = (rem_sz > scatter_elem_sz_prev) ?
1867 scatter_elem_sz_prev : rem_sz;
1850 p = sg_page_malloc(num, sfp->low_dma, &ret_sz); 1868 p = sg_page_malloc(num, sfp->low_dma, &ret_sz);
1851 if (!p) 1869 if (!p)
1852 return -ENOMEM; 1870 return -ENOMEM;
1853 1871
1872 if (num == scatter_elem_sz_prev) {
1873 if (unlikely(ret_sz > scatter_elem_sz_prev)) {
1874 scatter_elem_sz = ret_sz;
1875 scatter_elem_sz_prev = ret_sz;
1876 }
1877 }
1854 sg->page = p; 1878 sg->page = p;
1855 sg->length = ret_sz; 1879 sg->length = ret_sz;
1856 1880
@@ -2341,6 +2365,9 @@ sg_add_sfp(Sg_device * sdp, int dev)
2341 } 2365 }
2342 write_unlock_irqrestore(&sg_dev_arr_lock, iflags); 2366 write_unlock_irqrestore(&sg_dev_arr_lock, iflags);
2343 SCSI_LOG_TIMEOUT(3, printk("sg_add_sfp: sfp=0x%p\n", sfp)); 2367 SCSI_LOG_TIMEOUT(3, printk("sg_add_sfp: sfp=0x%p\n", sfp));
2368 if (unlikely(sg_big_buff != def_reserved_size))
2369 sg_big_buff = def_reserved_size;
2370
2344 sg_build_reserve(sfp, sg_big_buff); 2371 sg_build_reserve(sfp, sg_big_buff);
2345 SCSI_LOG_TIMEOUT(3, printk("sg_add_sfp: bufflen=%d, k_use_sg=%d\n", 2372 SCSI_LOG_TIMEOUT(3, printk("sg_add_sfp: bufflen=%d, k_use_sg=%d\n",
2346 sfp->reserve.bufflen, sfp->reserve.k_use_sg)); 2373 sfp->reserve.bufflen, sfp->reserve.k_use_sg));
@@ -2437,16 +2464,16 @@ sg_res_in_use(Sg_fd * sfp)
2437 return srp ? 1 : 0; 2464 return srp ? 1 : 0;
2438} 2465}
2439 2466
2440/* If retSzp==NULL want exact size or fail */ 2467/* The size fetched (value output via retSzp) set when non-NULL return */
2441static struct page * 2468static struct page *
2442sg_page_malloc(int rqSz, int lowDma, int *retSzp) 2469sg_page_malloc(int rqSz, int lowDma, int *retSzp)
2443{ 2470{
2444 struct page *resp = NULL; 2471 struct page *resp = NULL;
2445 gfp_t page_mask; 2472 gfp_t page_mask;
2446 int order, a_size; 2473 int order, a_size;
2447 int resSz = rqSz; 2474 int resSz;
2448 2475
2449 if (rqSz <= 0) 2476 if ((rqSz <= 0) || (NULL == retSzp))
2450 return resp; 2477 return resp;
2451 2478
2452 if (lowDma) 2479 if (lowDma)
@@ -2456,8 +2483,9 @@ sg_page_malloc(int rqSz, int lowDma, int *retSzp)
2456 2483
2457 for (order = 0, a_size = PAGE_SIZE; a_size < rqSz; 2484 for (order = 0, a_size = PAGE_SIZE; a_size < rqSz;
2458 order++, a_size <<= 1) ; 2485 order++, a_size <<= 1) ;
2486 resSz = a_size; /* rounded up if necessary */
2459 resp = alloc_pages(page_mask, order); 2487 resp = alloc_pages(page_mask, order);
2460 while ((!resp) && order && retSzp) { 2488 while ((!resp) && order) {
2461 --order; 2489 --order;
2462 a_size >>= 1; /* divide by 2, until PAGE_SIZE */ 2490 a_size >>= 1; /* divide by 2, until PAGE_SIZE */
2463 resp = alloc_pages(page_mask, order); /* try half */ 2491 resp = alloc_pages(page_mask, order); /* try half */
@@ -2466,8 +2494,7 @@ sg_page_malloc(int rqSz, int lowDma, int *retSzp)
2466 if (resp) { 2494 if (resp) {
2467 if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO)) 2495 if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
2468 memset(page_address(resp), 0, resSz); 2496 memset(page_address(resp), 0, resSz);
2469 if (retSzp) 2497 *retSzp = resSz;
2470 *retSzp = resSz;
2471 } 2498 }
2472 return resp; 2499 return resp;
2473} 2500}
diff --git a/include/scsi/sg.h b/include/scsi/sg.h
index 0a487fe26d4f..519c49a0fc11 100644
--- a/include/scsi/sg.h
+++ b/include/scsi/sg.h
@@ -11,26 +11,10 @@
11Original driver (sg.h): 11Original driver (sg.h):
12* Copyright (C) 1992 Lawrence Foard 12* Copyright (C) 1992 Lawrence Foard
13Version 2 and 3 extensions to driver: 13Version 2 and 3 extensions to driver:
14* Copyright (C) 1998 - 2003 Douglas Gilbert 14* Copyright (C) 1998 - 2006 Douglas Gilbert
15 15
16 Version: 3.5.29 (20030529) 16 Version: 3.5.34 (20060920)
17 This version is for 2.5 series kernels. 17 This version is for 2.6 series kernels.
18
19 Changes since 3.5.28 (20030308)
20 - fix bug introduced in version 3.1.24 (last segment of sgat list)
21 Changes since 3.5.27 (20020812)
22 - remove procfs entries: hosts, host_hdr + host_strs (now in sysfs)
23 - add sysfs sg driver params: def_reserved_size, allow_dio, version
24 - new boot option: "sg_allow_dio" and module parameter: "allow_dio"
25 - multiple internal changes due to scsi subsystem rework
26 Changes since 3.5.26 (20020708)
27 - re-add direct IO using Kai Makisara's work
28 - re-tab to 8, start using C99-isms
29 - simplify memory management
30 Changes since 3.5.25 (20020504)
31 - driverfs additions
32 - copy_to/from_user() fixes [William Stinson]
33 - disable kiobufs support
34 18
35 For a full changelog see http://www.torque.net/sg 19 For a full changelog see http://www.torque.net/sg
36 20
@@ -40,7 +24,7 @@ Map of SG verions to the Linux kernels in which they appear:
40 2.1.40 2.2.20 24 2.1.40 2.2.20
41 3.0.x optional version 3 sg driver for 2.2 series 25 3.0.x optional version 3 sg driver for 2.2 series
42 3.1.17++ 2.4.0++ 26 3.1.17++ 2.4.0++
43 3.5.23++ 2.5.0++ 27 3.5.30++ 2.6.0++
44 28
45Major new features in SG 3.x driver (cf SG 2.x drivers) 29Major new features in SG 3.x driver (cf SG 2.x drivers)
46 - SG_IO ioctl() combines function if write() and read() 30 - SG_IO ioctl() combines function if write() and read()
@@ -51,14 +35,15 @@ Major new features in SG 3.x driver (cf SG 2.x drivers)
51 data into kernel buffers and then use the CPU to copy the data into the 35 data into kernel buffers and then use the CPU to copy the data into the
52 user space (vice versa for writes). That is called "indirect" IO due to 36 user space (vice versa for writes). That is called "indirect" IO due to
53 the double handling of data. There are two methods offered to remove the 37 the double handling of data. There are two methods offered to remove the
54 redundant copy: 1) direct IO which uses the kernel kiobuf mechanism and 38 redundant copy: 1) direct IO and 2) using the mmap() system call to map
55 2) using the mmap() system call to map the reserve buffer (this driver has 39 the reserve buffer (this driver has one reserve buffer per fd) into the
56 one reserve buffer per fd) into the user space. Both have their advantages. 40 user space. Both have their advantages.
57 In terms of absolute speed mmap() is faster. If speed is not a concern, 41 In terms of absolute speed mmap() is faster. If speed is not a concern,
58 indirect IO should be fine. Read the documentation for more information. 42 indirect IO should be fine. Read the documentation for more information.
59 43
60 ** N.B. To use direct IO 'echo 1 > /proc/scsi/sg/allow_dio' may be 44 ** N.B. To use direct IO 'echo 1 > /proc/scsi/sg/allow_dio' or
61 needed. That pseudo file's content is defaulted to 0. ** 45 'echo 1 > /sys/module/sg/parameters/allow_dio' is needed.
46 That attribute is 0 by default. **
62 47
63 Historical note: this SCSI pass-through driver has been known as "sg" for 48 Historical note: this SCSI pass-through driver has been known as "sg" for
64 a decade. In broader kernel discussions "sg" is used to refer to scatter 49 a decade. In broader kernel discussions "sg" is used to refer to scatter
@@ -72,20 +57,17 @@ Major new features in SG 3.x driver (cf SG 2.x drivers)
72 http://www.torque.net/sg/p/sg_v3_ho.html 57 http://www.torque.net/sg/p/sg_v3_ho.html
73 This is a rendering from DocBook source [change the extension to "sgml" 58 This is a rendering from DocBook source [change the extension to "sgml"
74 or "xml"]. There are renderings in "ps", "pdf", "rtf" and "txt" (soon). 59 or "xml"]. There are renderings in "ps", "pdf", "rtf" and "txt" (soon).
60 The SG_IO ioctl is now found in other parts kernel (e.g. the block layer).
61 For more information see http://www.torque.net/sg/sg_io.html
75 62
76 The older, version 2 documents discuss the original sg interface in detail: 63 The older, version 2 documents discuss the original sg interface in detail:
77 http://www.torque.net/sg/p/scsi-generic.txt 64 http://www.torque.net/sg/p/scsi-generic.txt
78 http://www.torque.net/sg/p/scsi-generic_long.txt 65 http://www.torque.net/sg/p/scsi-generic_long.txt
79 A version of this document (potentially out of date) may also be found in 66 Also available: <kernel_source>/Documentation/scsi/scsi-generic.txt
80 the kernel source tree, probably at:
81 Documentation/scsi/scsi-generic.txt .
82 67
83 Utility and test programs are available at the sg web site. They are 68 Utility and test programs are available at the sg web site. They are
84 bundled as sg_utils (for the lk 2.2 series) and sg3_utils (for the 69 packaged as sg3_utils (for the lk 2.4 and 2.6 series) and sg_utils
85 lk 2.4 series). 70 (for the lk 2.2 series).
86
87 There is a HOWTO on the Linux SCSI subsystem in the lk 2.4 series at:
88 http://www.linuxdoc.org/HOWTO/SCSI-2.4-HOWTO
89*/ 71*/
90 72
91 73
@@ -238,13 +220,12 @@ typedef struct sg_req_info { /* used by SG_GET_REQUEST_TABLE ioctl() */
238#define SG_GET_ACCESS_COUNT 0x2289 220#define SG_GET_ACCESS_COUNT 0x2289
239 221
240 222
241#define SG_SCATTER_SZ (8 * 4096) /* PAGE_SIZE not available to user */ 223#define SG_SCATTER_SZ (8 * 4096)
242/* Largest size (in bytes) a single scatter-gather list element can have. 224/* Largest size (in bytes) a single scatter-gather list element can have.
243 The value must be a power of 2 and <= (PAGE_SIZE * 32) [131072 bytes on 225 The value used by the driver is 'max(SG_SCATTER_SZ, PAGE_SIZE)'.
244 i386]. The minimum value is PAGE_SIZE. If scatter-gather not supported 226 This value should be a power of 2 (and may be rounded up internally).
245 by adapter then this value is the largest data block that can be 227 If scatter-gather is not supported by adapter then this value is the
246 read/written by a single scsi command. The user can find the value of 228 largest data block that can be read/written by a single scsi command. */
247 PAGE_SIZE by calling getpagesize() defined in unistd.h . */
248 229
249#define SG_DEFAULT_RETRIES 0 230#define SG_DEFAULT_RETRIES 0
250 231