From: <vl...@us...> - 2008-02-01 10:33:52
|
Revision: 252 http://scst.svn.sourceforge.net/scst/?rev=252&view=rev Author: vlnb Date: 2008-02-01 02:33:47 -0800 (Fri, 01 Feb 2008) Log Message: ----------- Forgotten in the previous commit kernel patches Added Paths: ----------- trunk/iscsi-scst/kernel/patches/put_page_callback-2.6.24.patch trunk/scst/kernel/scst_exec_req_fifo-2.6.24.patch Added: trunk/iscsi-scst/kernel/patches/put_page_callback-2.6.24.patch =================================================================== --- trunk/iscsi-scst/kernel/patches/put_page_callback-2.6.24.patch (rev 0) +++ trunk/iscsi-scst/kernel/patches/put_page_callback-2.6.24.patch 2008-02-01 10:33:47 UTC (rev 252) @@ -0,0 +1,259 @@ +diff -upkr linux-2.6.24/include/linux/mm_types.h linux-2.6.24/include/linux/mm_types.h +--- linux-2.6.24/include/linux/mm_types.h 2008-01-25 01:58:37.000000000 +0300 ++++ linux-2.6.24/include/linux/mm_types.h 2008-01-28 11:11:16.000000000 +0300 +@@ -88,6 +88,15 @@ struct page { + void *virtual; /* Kernel virtual address (NULL if + not kmapped, ie. highmem) */ + #endif /* WANT_PAGE_VIRTUAL */ ++ /* ++ * Used to implement support for notification on zero-copy TCP transfer ++ * completion. Not good to have this field here, it's better to have ++ * it in struct sk_buff, but it would make the code much more ++ * complicated and fragile, if maintained as a separate patch, since all ++ * skb then would have to contain only pages with the same value in this ++ * field. ++ */ ++ void *net_priv; + }; + + /* +diff -upkr linux-2.6.24/include/linux/net.h linux-2.6.24/include/linux/net.h +--- linux-2.6.24/include/linux/net.h 2008-01-25 01:58:37.000000000 +0300 ++++ linux-2.6.24/include/linux/net.h 2008-01-28 11:11:16.000000000 +0300 +@@ -58,6 +58,7 @@ typedef enum { + #ifdef __KERNEL__ + #include <linux/stringify.h> + #include <linux/random.h> ++#include <linux/mm.h> + + #define SOCK_ASYNC_NOSPACE 0 + #define SOCK_ASYNC_WAITDATA 1 +@@ -332,5 +333,30 @@ extern int net_msg_cost; + extern int net_msg_burst; + #endif + ++/* Support for notification on zero-copy TCP transfer completion */ ++#define NET_PAGE_CALLBACKS_DEFINED ++typedef void (*net_get_page_callback_t)(struct page *page); ++typedef void (*net_put_page_callback_t)(struct page *page); ++ ++extern net_get_page_callback_t net_get_page_callback; ++extern net_put_page_callback_t net_put_page_callback; ++ ++extern int net_set_get_put_page_callbacks( ++ net_get_page_callback_t get_callback, ++ net_put_page_callback_t put_callback); ++ ++static inline void net_get_page(struct page *page) ++{ ++ if (page->net_priv != 0) ++ net_get_page_callback(page); ++ get_page(page); ++} ++static inline void net_put_page(struct page *page) ++{ ++ if (page->net_priv != 0) ++ net_put_page_callback(page); ++ put_page(page); ++} ++ + #endif /* __KERNEL__ */ + #endif /* _LINUX_NET_H */ +diff -upkr linux-2.6.24/net/core/skbuff.c linux-2.6.24/net/core/skbuff.c +--- linux-2.6.24/net/core/skbuff.c 2008-01-25 01:58:37.000000000 +0300 ++++ linux-2.6.24/net/core/skbuff.c 2008-01-28 11:11:16.000000000 +0300 +@@ -262,7 +262,7 @@ static void skb_release_data(struct sk_b + if (skb_shinfo(skb)->nr_frags) { + int i; + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) +- put_page(skb_shinfo(skb)->frags[i].page); ++ net_put_page(skb_shinfo(skb)->frags[i].page); + } + + if (skb_shinfo(skb)->frag_list) +@@ -596,7 +596,7 @@ struct sk_buff *pskb_copy(struct sk_buff + + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { + skb_shinfo(n)->frags[i] = skb_shinfo(skb)->frags[i]; +- get_page(skb_shinfo(n)->frags[i].page); ++ net_get_page(skb_shinfo(n)->frags[i].page); + } + skb_shinfo(n)->nr_frags = i; + } +@@ -659,7 +659,7 @@ int pskb_expand_head(struct sk_buff *skb + sizeof(struct skb_shared_info)); + + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) +- get_page(skb_shinfo(skb)->frags[i].page); ++ net_get_page(skb_shinfo(skb)->frags[i].page); + + if (skb_shinfo(skb)->frag_list) + skb_clone_fraglist(skb); +@@ -856,7 +856,7 @@ drop_pages: + skb_shinfo(skb)->nr_frags = i; + + for (; i < nfrags; i++) +- put_page(skb_shinfo(skb)->frags[i].page); ++ net_put_page(skb_shinfo(skb)->frags[i].page); + + if (skb_shinfo(skb)->frag_list) + skb_drop_fraglist(skb); +@@ -1025,7 +1025,7 @@ pull_pages: + k = 0; + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { + if (skb_shinfo(skb)->frags[i].size <= eat) { +- put_page(skb_shinfo(skb)->frags[i].page); ++ net_put_page(skb_shinfo(skb)->frags[i].page); + eat -= skb_shinfo(skb)->frags[i].size; + } else { + skb_shinfo(skb)->frags[k] = skb_shinfo(skb)->frags[i]; +@@ -1594,7 +1594,7 @@ static inline void skb_split_no_header(s + * where splitting is expensive. + * 2. Split is accurately. We make this. + */ +- get_page(skb_shinfo(skb)->frags[i].page); ++ net_get_page(skb_shinfo(skb)->frags[i].page); + skb_shinfo(skb1)->frags[0].page_offset += len - pos; + skb_shinfo(skb1)->frags[0].size -= len - pos; + skb_shinfo(skb)->frags[i].size = len - pos; +@@ -1970,7 +1970,7 @@ struct sk_buff *skb_segment(struct sk_bu + BUG_ON(i >= nfrags); + + *frag = skb_shinfo(skb)->frags[i]; +- get_page(frag->page); ++ net_get_page(frag->page); + size = frag->size; + + if (pos < offset) { +diff -upkr linux-2.6.24/net/core/utils.c linux-2.6.24/net/core/utils.c +--- linux-2.6.24/net/core/utils.c 2008-01-25 01:58:37.000000000 +0300 ++++ linux-2.6.24/net/core/utils.c 2008-01-28 11:11:16.000000000 +0300 +@@ -25,6 +25,7 @@ + #include <linux/random.h> + #include <linux/percpu.h> + #include <linux/init.h> ++#include <linux/skbuff.h> + #include <net/sock.h> + + #include <asm/byteorder.h> +@@ -36,6 +37,9 @@ int net_msg_burst __read_mostly = 10; + int net_msg_warn __read_mostly = 1; + EXPORT_SYMBOL(net_msg_warn); + ++net_get_page_callback_t net_get_page_callback __read_mostly; ++net_put_page_callback_t net_put_page_callback __read_mostly; ++ + /* + * All net warning printk()s should be guarded by this function. + */ +@@ -293,3 +297,32 @@ out: + } + + EXPORT_SYMBOL(in6_pton); ++ ++int net_set_get_put_page_callbacks( ++ net_get_page_callback_t get_callback, ++ net_put_page_callback_t put_callback) ++{ ++ int res = 0; ++ ++ if ((net_get_page_callback != NULL) && (get_callback != NULL) && ++ (net_get_page_callback != get_callback)) { ++ res = -EBUSY; ++ goto out; ++ } ++ ++ if ((net_put_page_callback != NULL) && (put_callback != NULL) && ++ (net_put_page_callback != put_callback)) { ++ res = -EBUSY; ++ goto out; ++ } ++ ++ net_get_page_callback = get_callback; ++ net_put_page_callback = put_callback; ++ ++out: ++ return res; ++} ++EXPORT_SYMBOL(net_set_get_put_page_callbacks); ++ ++EXPORT_SYMBOL(net_get_page_callback); ++EXPORT_SYMBOL(net_put_page_callback); +diff -upkr linux-2.6.24/net/ipv4/ip_output.c linux-2.6.24/net/ipv4/ip_output.c +--- linux-2.6.24/net/ipv4/ip_output.c 2008-01-25 01:58:37.000000000 +0300 ++++ linux-2.6.24/net/ipv4/ip_output.c 2008-01-28 11:11:16.000000000 +0300 +@@ -999,7 +999,7 @@ alloc_new_skb: + err = -EMSGSIZE; + goto error; + } +- get_page(page); ++ net_get_page(page); + skb_fill_page_desc(skb, i, page, sk->sk_sndmsg_off, 0); + frag = &skb_shinfo(skb)->frags[i]; + } +@@ -1157,7 +1157,7 @@ ssize_t ip_append_page(struct sock *sk, + if (skb_can_coalesce(skb, i, page, offset)) { + skb_shinfo(skb)->frags[i-1].size += len; + } else if (i < MAX_SKB_FRAGS) { +- get_page(page); ++ net_get_page(page); + skb_fill_page_desc(skb, i, page, offset, len); + } else { + err = -EMSGSIZE; +diff -upkr linux-2.6.24/net/ipv4/tcp.c linux-2.6.24/net/ipv4/tcp.c +--- linux-2.6.24/net/ipv4/tcp.c 2008-01-25 01:58:37.000000000 +0300 ++++ linux-2.6.24/net/ipv4/tcp.c 2008-01-28 11:11:16.000000000 +0300 +@@ -561,7 +561,7 @@ new_segment: + if (can_coalesce) { + skb_shinfo(skb)->frags[i - 1].size += copy; + } else { +- get_page(page); ++ net_get_page(page); + skb_fill_page_desc(skb, i, page, offset, copy); + } + +@@ -766,7 +766,7 @@ new_segment: + goto new_segment; + } else if (page) { + if (off == PAGE_SIZE) { +- put_page(page); ++ net_put_page(page); + TCP_PAGE(sk) = page = NULL; + off = 0; + } +@@ -807,9 +807,9 @@ new_segment: + } else { + skb_fill_page_desc(skb, i, page, off, copy); + if (TCP_PAGE(sk)) { +- get_page(page); ++ net_get_page(page); + } else if (off + copy < PAGE_SIZE) { +- get_page(page); ++ net_get_page(page); + TCP_PAGE(sk) = page; + } + } +diff -upkr linux-2.6.24/net/ipv4/tcp_output.c linux-2.6.24/net/ipv4/tcp_output.c +--- linux-2.6.24/net/ipv4/tcp_output.c 2008-01-25 01:58:37.000000000 +0300 ++++ linux-2.6.24/net/ipv4/tcp_output.c 2008-01-28 11:11:16.000000000 +0300 +@@ -794,7 +794,7 @@ static void __pskb_trim_head(struct sk_b + k = 0; + for (i=0; i<skb_shinfo(skb)->nr_frags; i++) { + if (skb_shinfo(skb)->frags[i].size <= eat) { +- put_page(skb_shinfo(skb)->frags[i].page); ++ net_put_page(skb_shinfo(skb)->frags[i].page); + eat -= skb_shinfo(skb)->frags[i].size; + } else { + skb_shinfo(skb)->frags[k] = skb_shinfo(skb)->frags[i]; +diff -upkr linux-2.6.24/net/ipv6/ip6_output.c linux-2.6.24/net/ipv6/ip6_output.c +--- linux-2.6.24/net/ipv6/ip6_output.c 2008-01-25 01:58:37.000000000 +0300 ++++ linux-2.6.24/net/ipv6/ip6_output.c 2008-01-28 11:11:16.000000000 +0300 +@@ -1299,7 +1299,7 @@ alloc_new_skb: + err = -EMSGSIZE; + goto error; + } +- get_page(page); ++ net_get_page(page); + skb_fill_page_desc(skb, i, page, sk->sk_sndmsg_off, 0); + frag = &skb_shinfo(skb)->frags[i]; + } Added: trunk/scst/kernel/scst_exec_req_fifo-2.6.24.patch =================================================================== --- trunk/scst/kernel/scst_exec_req_fifo-2.6.24.patch (rev 0) +++ trunk/scst/kernel/scst_exec_req_fifo-2.6.24.patch 2008-02-01 10:33:47 UTC (rev 252) @@ -0,0 +1,109 @@ +diff -upkr linux-2.6.24/drivers/scsi/scsi_lib.c linux-2.6.24/drivers/scsi/scsi_lib.c +--- linux-2.6.24/drivers/scsi/scsi_lib.c 2008-01-25 01:58:37.000000000 +0300 ++++ linux-2.6.24/drivers/scsi/scsi_lib.c 2008-01-28 11:10:30.000000000 +0300 +@@ -361,7 +361,7 @@ free_bios: + } + + /** +- * scsi_execute_async - insert request ++ * __scsi_execute_async - insert request + * @sdev: scsi device + * @cmd: scsi command + * @cmd_len: length of scsi cdb +@@ -372,11 +372,14 @@ free_bios: + * @timeout: request timeout in seconds + * @retries: number of times to retry request + * @flags: or into request flags ++ * @at_head: insert request at head or tail of queue + **/ +-int scsi_execute_async(struct scsi_device *sdev, const unsigned char *cmd, ++static inline int __scsi_execute_async(struct scsi_device *sdev, ++ const unsigned char *cmd, + int cmd_len, int data_direction, void *buffer, unsigned bufflen, + int use_sg, int timeout, int retries, void *privdata, +- void (*done)(void *, char *, int, int), gfp_t gfp) ++ void (*done)(void *, char *, int, int), gfp_t gfp, ++ int at_head) + { + struct request *req; + struct scsi_io_context *sioc; +@@ -413,7 +416,7 @@ int scsi_execute_async(struct scsi_devic + sioc->data = privdata; + sioc->done = done; + +- blk_execute_rq_nowait(req->q, NULL, req, 1, scsi_end_async); ++ blk_execute_rq_nowait(req->q, NULL, req, at_head, scsi_end_async); + return 0; + + free_req: +@@ -422,8 +425,53 @@ free_sense: + kmem_cache_free(scsi_io_context_cache, sioc); + return DRIVER_ERROR << 24; + } ++ ++/** ++ * scsi_execute_async - insert request ++ * @sdev: scsi device ++ * @cmd: scsi command ++ * @cmd_len: length of scsi cdb ++ * @data_direction: data direction ++ * @buffer: data buffer (this can be a kernel buffer or scatterlist) ++ * @bufflen: len of buffer ++ * @use_sg: if buffer is a scatterlist this is the number of elements ++ * @timeout: request timeout in seconds ++ * @retries: number of times to retry request ++ * @flags: or into request flags ++ **/ ++int scsi_execute_async(struct scsi_device *sdev, const unsigned char *cmd, ++ int cmd_len, int data_direction, void *buffer, unsigned bufflen, ++ int use_sg, int timeout, int retries, void *privdata, ++ void (*done)(void *, char *, int, int), gfp_t gfp) ++{ ++ return __scsi_execute_async(sdev, cmd, cmd_len, data_direction, buffer, ++ bufflen, use_sg, timeout, retries, privdata, done, gfp, 1); ++} + EXPORT_SYMBOL_GPL(scsi_execute_async); + ++/** ++ * scsi_execute_async_fifo - insert request at tail, in FIFO order ++ * @sdev: scsi device ++ * @cmd: scsi command ++ * @cmd_len: length of scsi cdb ++ * @data_direction: data direction ++ * @buffer: data buffer (this can be a kernel buffer or scatterlist) ++ * @bufflen: len of buffer ++ * @use_sg: if buffer is a scatterlist this is the number of elements ++ * @timeout: request timeout in seconds ++ * @retries: number of times to retry request ++ * @flags: or into request flags ++ **/ ++int scsi_execute_async_fifo(struct scsi_device *sdev, const unsigned char *cmd, ++ int cmd_len, int data_direction, void *buffer, unsigned bufflen, ++ int use_sg, int timeout, int retries, void *privdata, ++ void (*done)(void *, char *, int, int), gfp_t gfp) ++{ ++ return __scsi_execute_async(sdev, cmd, cmd_len, data_direction, buffer, ++ bufflen, use_sg, timeout, retries, privdata, done, gfp, 0); ++} ++EXPORT_SYMBOL_GPL(scsi_execute_async_fifo); ++ + /* + * Function: scsi_init_cmd_errh() + * +diff -upkr linux-2.6.24/include/scsi/scsi_device.h linux-2.6.24/include/scsi/scsi_device.h +--- linux-2.6.24/include/scsi/scsi_device.h 2008-01-25 01:58:37.000000000 +0300 ++++ linux-2.6.24/include/scsi/scsi_device.h 2008-01-28 11:10:30.000000000 +0300 +@@ -331,6 +331,13 @@ extern int scsi_execute_async(struct scs + int timeout, int retries, void *privdata, + void (*done)(void *, char *, int, int), + gfp_t gfp); ++#define SCSI_EXEC_REQ_FIFO_DEFINED ++extern int scsi_execute_async_fifo(struct scsi_device *sdev, ++ const unsigned char *cmd, int cmd_len, int data_direction, ++ void *buffer, unsigned bufflen, int use_sg, ++ int timeout, int retries, void *privdata, ++ void (*done)(void *, char *, int, int), ++ gfp_t gfp); + + static inline int __must_check scsi_device_reprobe(struct scsi_device *sdev) + { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |