From 2239c07de9a32eb84e9974c25e2d3ba364b30ea8 Mon Sep 17 00:00:00 2001 From: David Malone Date: Thu, 8 Mar 2001 16:28:10 +0000 Subject: [PATCH] Make the wait for sendfile buffers interruptable. Stops one process consuming them all and then getting stuck. Reviewed by: dg Reviewed by: bmilekic Observed by: Andreas Persson --- sys/kern/uipc_syscalls.c | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c index c46b7eafba50..d849b216e29f 100644 --- a/sys/kern/uipc_syscalls.c +++ b/sys/kern/uipc_syscalls.c @@ -1454,11 +1454,17 @@ static struct sf_buf * sf_buf_alloc() { struct sf_buf *sf; + int error; mtx_lock(&sf_freelist.sf_lock); while ((sf = SLIST_FIRST(&sf_freelist.sf_head)) == NULL) { sf_buf_alloc_want++; - msleep(&sf_freelist, &sf_freelist.sf_lock, PVM, "sfbufa", 0); + error = msleep(&sf_freelist, &sf_freelist.sf_lock, PVM|PCATCH, + "sfbufa", 0); + if (error != 0) { + sf_buf_alloc_want--; + break; + } } SLIST_REMOVE_HEAD(&sf_freelist.sf_head, free_list); mtx_unlock(&sf_freelist.sf_lock); @@ -1707,12 +1713,26 @@ sendfile(struct proc *p, struct sendfile_args *uap) } } + + /* + * Get a sendfile buf. We usually wait as long as necessary, + * but this wait can be interrupted. + */ + if ((sf = sf_buf_alloc()) == NULL) { + s = splvm(); + vm_page_unwire(pg, 0); + if (pg->wire_count == 0 && pg->object == NULL) + vm_page_free(pg); + splx(s); + sbunlock(&so->so_snd); + error = EINTR; + goto done; + } + /* * Allocate a kernel virtual page and insert the physical page * into it. */ - - sf = sf_buf_alloc(); sf->m = pg; pmap_qenter(sf->kva, &pg, 1); /* @@ -1722,6 +1742,7 @@ sendfile(struct proc *p, struct sendfile_args *uap) if (m == NULL) { error = ENOBUFS; sf_buf_free((void *)sf->kva, NULL); + sbunlock(&so->so_snd); goto done; } /*