Re: Linux 2.4.0test1-ac2

From: Manfred Spraul (manfreds@colorfullife.com)
Date: Fri May 26 2000 - 12:27:35 EST


Tigran Aivazian wrote:
>
> On Fri, 26 May 2000, Alan Cox wrote:
> > Next on the list - sorting out poll
>
> what's wrong with poll? Can I help? Do you mean Manfred's recent suggested
> optimizations or is there something wrong with the chunk-allocatable poll?
> Or is this unrelated to pollfd allocation?
>
I assume Alan want's to change the pollwait allocation.
I've attached my updated & tested patch vs. 2.3.99-pre9, I'll download
test1-ac2 ASAP.

--
	Manfred

// $Header$ // Kernel Version: // VERSION = 2 // PATCHLEVEL = 3 // SUBLEVEL = 99 // EXTRAVERSION = -pre9 --- 2.3/fs/select.c Thu Apr 27 11:27:14 2000 +++ build-2.3/fs/select.c Fri May 26 19:23:05 2000 @@ -52,6 +52,7 @@ if(out==NULL) return NULL; out->nr = 0; + out->err = 0; out->entry = (struct poll_table_entry *)(out + 1); out->next = NULL; nfds -=__MAX_POLL_TABLE_ENTRIES; @@ -97,19 +98,36 @@ void __pollwait(struct file * filp, wait_queue_head_t * wait_address, poll_table *p) { + poll_table* walk = p; for (;;) { - if (p->nr < __MAX_POLL_TABLE_ENTRIES) { + if (walk->nr < __MAX_POLL_TABLE_ENTRIES) { struct poll_table_entry * entry; - entry = p->entry + p->nr; +ok_table: + entry = walk->entry + walk->nr; get_file(filp); entry->filp = filp; entry->wait_address = wait_address; init_waitqueue_entry(&entry->wait, current); add_wait_queue(wait_address,&entry->wait); - p->nr++; + walk->nr++; return; } - p = p->next; + if (walk->next == NULL) { + poll_table *tmp; + current->state=TASK_RUNNING; + tmp = (poll_table *) __get_free_page(GFP_KERNEL); + if (!tmp) { + p->err=-ENOMEM; + return; + } + tmp->nr = 0; + tmp->entry = (struct poll_table_entry *)(tmp + 1); + tmp->next = NULL; + walk->next = tmp; + walk = tmp; + goto ok_table; + } + walk = walk->next; } } @@ -226,11 +244,16 @@ wait = NULL; } } - wait = NULL; if (retval || !__timeout || signal_pending(current)) break; + if(orig_wait->err) { + retval=orig_wait->err; + goto out; + } + wait = NULL; __timeout = schedule_timeout(__timeout); } +out: current->state = TASK_RUNNING; free_wait(orig_wait); @@ -382,6 +405,7 @@ struct pollfd *fds[], poll_table *wait, long timeout) { int count = 0; + poll_table* orig_wait = wait; for (;;) { unsigned int i; @@ -391,11 +415,16 @@ do_pollfd(POLLFD_PER_PAGE, fds[i], &wait, &count); if (nleft) do_pollfd(nleft, fds[nchunks], &wait, &count); - wait = NULL; if (count || !timeout || signal_pending(current)) break; + if(orig_wait->err) { + count=orig_wait->err; + goto out; + } + wait=NULL; timeout = schedule_timeout(timeout); } +out: current->state = TASK_RUNNING; return count; } --- 2.3/include/linux/poll.h Tue Jun 1 16:29:17 1999 +++ build-2.3/include/linux/poll.h Fri May 26 19:12:25 2000 @@ -20,6 +20,7 @@ typedef struct poll_table_struct { struct poll_table_struct * next; unsigned int nr; + int err; struct poll_table_entry * entry; } poll_table;

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Wed May 31 2000 - 21:00:16 EST