diff -urN linux-2.4.13-manfred/fs/pipe.c linux-2.4.13-manfred-up/fs/pipe.c --- linux-2.4.13-manfred/fs/pipe.c Tue Nov 6 15:23:41 2001 +++ linux-2.4.13-manfred-up/fs/pipe.c Tue Nov 6 11:25:28 2001 @@ -28,6 +28,8 @@ * -- Julian Bradfield 1999-06-07. */ +struct pipe_stat_t pipe_stat; + /* Drop the inode semaphore and wait for a pipe event, atomically */ void pipe_wait(struct inode * inode) { @@ -158,7 +160,7 @@ * case. Write into the internal buffer before * checking for signals/error conditions. */ - size_t j = min((size_t)PIPE_SIZE, pio->len); + size_t j = min((size_t)PIPE_SIZE(*inode), pio->len); if (PIPE_LEN(*inode)) BUG(); if (PIPE_START(*inode)) BUG(); if (!copy_from_user(PIPE_BASE(*inode), buf + i, j)) { @@ -199,8 +201,8 @@ int offset = PIPE_START(*inode)%PIPE_BUF; if (chars > count) chars = count; - if (chars > PIPE_SIZE-offset) - chars = PIPE_SIZE-offset; + if (chars > PIPE_SIZE(*inode)-offset) + chars = PIPE_SIZE(*inode)-offset; if (unlikely(copy_to_user(buf, pipebuf+offset, chars))) { if (!read) read = -EFAULT; @@ -313,11 +315,11 @@ if (PIPE_PIOLEN(*inode)) goto skip_int_buf; /* write to internal buffer - could be cyclic */ - while(start = PIPE_LEN(*inode),chars = PIPE_SIZE - start, chars >= min) { + while(start = PIPE_LEN(*inode),chars = PIPE_SIZE(*inode) - start, chars >= min) { start += PIPE_START(*inode); - start %= PIPE_SIZE; - if (chars > PIPE_BUF - start) - chars = PIPE_BUF - start; + start %= PIPE_SIZE(*inode); + if (chars > PIPE_SIZE(*inode) - start) + chars = PIPE_SIZE(*inode) - start; if (chars > count) chars = count; if (unlikely(copy_from_user(PIPE_BASE(*inode)+start, @@ -457,7 +459,7 @@ if (!PIPE_READERS(*inode) && !PIPE_WRITERS(*inode)) { struct pipe_inode_info *info = inode->i_pipe; inode->i_pipe = NULL; - free_page((unsigned long) info->base); + free_pages((unsigned long) info->base, info->order); kfree(info); } else { wake_up_interruptible(PIPE_WAIT(*inode)); @@ -591,8 +593,12 @@ struct inode* pipe_new(struct inode* inode) { unsigned long page; + int pipe_order = pipe_stat.pipe_size_order; + + if (pipe_order > MAX_PIPE_ORDER) + pipe_order = MAX_PIPE_ORDER; - page = __get_free_page(GFP_USER); + page = __get_free_pages(GFP_USER, pipe_order); if (!page) return NULL; @@ -606,10 +612,11 @@ PIPE_START(*inode) = PIPE_LEN(*inode) = PIPE_PIOLEN(*inode) = 0; PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 0; PIPE_RCOUNTER(*inode) = PIPE_WCOUNTER(*inode) = 1; + PIPE_ORDER(*inode) = pipe_order; return inode; fail_page: - free_page(page); + free_pages(page, pipe_order); return NULL; } @@ -724,7 +731,7 @@ close_f12_inode_i: put_unused_fd(i); close_f12_inode: - free_page((unsigned long) PIPE_BASE(*inode)); + free_pages((unsigned long) PIPE_BASE(*inode), PIPE_ORDER(*inode)); kfree(inode->i_pipe); inode->i_pipe = NULL; iput(inode); diff -urN linux-2.4.13-manfred/include/linux/pipe_fs_i.h linux-2.4.13-manfred-up/include/linux/pipe_fs_i.h --- linux-2.4.13-manfred/include/linux/pipe_fs_i.h Tue Nov 6 15:23:41 2001 +++ linux-2.4.13-manfred-up/include/linux/pipe_fs_i.h Mon Nov 5 17:35:01 2001 @@ -2,6 +2,7 @@ #define _LINUX_PIPE_FS_I_H #define PIPEFS_MAGIC 0x50495045 +#define MAX_PIPE_ORDER 3 struct pipe_inode_info { wait_queue_head_t wait; char *base; @@ -13,12 +14,21 @@ unsigned int writers; unsigned int r_counter; unsigned int w_counter; + unsigned int order; }; +struct pipe_stat_t{ + int pipe_size_order; + int pipe_seg_order; +}; + +extern struct pipe_stat_t pipe_stat; + /* Differs from PIPE_BUF in that PIPE_SIZE is the length of the actual memory allocation, whereas PIPE_BUF makes atomicity guarantees. */ -#define PIPE_SIZE PAGE_SIZE +#define PIPE_SIZE(inode) ((1 << PIPE_ORDER(inode)) * PAGE_SIZE) +#define PIPE_ORDER(inode) ((inode).i_pipe->order) #define PIPE_SEM(inode) (&(inode).i_sem) #define PIPE_WAIT(inode) (&(inode).i_pipe->wait) #define PIPE_BASE(inode) ((inode).i_pipe->base) @@ -31,8 +41,8 @@ #define PIPE_RCOUNTER(inode) ((inode).i_pipe->r_counter) #define PIPE_WCOUNTER(inode) ((inode).i_pipe->w_counter) -#define PIPE_FREE(inode) (PIPE_SIZE - PIPE_LEN(inode)) -#define PIPE_END(inode) ((PIPE_START(inode) + PIPE_LEN(inode)) & (PIPE_SIZE-1)) +#define PIPE_FREE(inode) (PIPE_SIZE(inode) - PIPE_LEN(inode)) +#define PIPE_END(inode) ((PIPE_START(inode) + PIPE_LEN(inode)) & (PIPE_SIZE(inode)-1)) /* Drop the inode semaphore and wait for a pipe event, atomically */ void pipe_wait(struct inode * inode); diff -urN linux-2.4.13-manfred/include/linux/sysctl.h linux-2.4.13-manfred-up/include/linux/sysctl.h --- linux-2.4.13-manfred/include/linux/sysctl.h Thu Oct 11 02:44:34 2001 +++ linux-2.4.13-manfred-up/include/linux/sysctl.h Tue Nov 6 14:20:00 2001 @@ -540,6 +540,7 @@ FS_LEASES=13, /* int: leases enabled */ FS_DIR_NOTIFY=14, /* int: directory notification enabled */ FS_LEASE_TIME=15, /* int: maximum time to wait for a lease break */ + FS_PIPE_SIZE=16, /* int: number of pages allocated for PIPE */ }; /* CTL_DEBUG names: */ diff -urN linux-2.4.13-manfred/kernel/sysctl.c linux-2.4.13-manfred-up/kernel/sysctl.c --- linux-2.4.13-manfred/kernel/sysctl.c Fri Oct 5 15:23:53 2001 +++ linux-2.4.13-manfred-up/kernel/sysctl.c Mon Nov 5 17:21:18 2001 @@ -302,6 +302,8 @@ sizeof(int), 0644, NULL, &proc_dointvec}, {FS_LEASE_TIME, "lease-break-time", &lease_break_time, sizeof(int), 0644, NULL, &proc_dointvec}, + {FS_PIPE_SIZE, "pipe-sz", &pipe_stat, 2*sizeof(int), + 0644, NULL, &proc_dointvec}, {0} };