summaryrefslogtreecommitdiffstats
path: root/sys/kern/uipc_syscalls.c
diff options
context:
space:
mode:
authorbmilekic <bmilekic@FreeBSD.org>2000-11-04 07:16:08 +0000
committerbmilekic <bmilekic@FreeBSD.org>2000-11-04 07:16:08 +0000
commit8b319d105d5e923a51a030154a02faab2552df6f (patch)
tree6f6051e3409f8d5faf47c7079b4292f37e23140c /sys/kern/uipc_syscalls.c
parentb01bea2a9440e72ec9b2d5bfc81967267f2416cc (diff)
downloadFreeBSD-src-8b319d105d5e923a51a030154a02faab2552df6f.zip
FreeBSD-src-8b319d105d5e923a51a030154a02faab2552df6f.tar.gz
Setup and put to use the mutex lock for sf_freelist, the sendfile(2) bufs
freelist. Should now be thread-friendly, in part. Note: More work is needed in uipc_syscalls.c, but it will have to wait until the socket locking issues are at least 80% implemented and committed.
Diffstat (limited to 'sys/kern/uipc_syscalls.c')
-rw-r--r--sys/kern/uipc_syscalls.c27
1 files changed, 18 insertions, 9 deletions
diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c
index e231a83..8cfbf80 100644
--- a/sys/kern/uipc_syscalls.c
+++ b/sys/kern/uipc_syscalls.c
@@ -84,7 +84,15 @@ static int getsockname1 __P((struct proc *p, struct getsockname_args *uap,
static int getpeername1 __P((struct proc *p, struct getpeername_args *uap,
int compat));
-static SLIST_HEAD(, sf_buf) sf_freelist;
+/*
+ * Expanded sf_freelist head. Really an SLIST_HEAD() in disguise, with the
+ * additional sf_lock mutex.
+ */
+static struct {
+ struct sf_buf *slh_first;
+ struct mtx sf_lock;
+} sf_freelist;
+
static vm_offset_t sf_base;
static struct sf_buf *sf_bufs;
static int sf_buf_alloc_want;
@@ -1327,6 +1335,8 @@ sf_buf_init(void *arg)
{
int i;
+ mtx_init(&sf_freelist.sf_lock, "sf_bufs list lock", MTX_DEF);
+ mtx_enter(&sf_freelist.sf_lock, MTX_DEF);
SLIST_INIT(&sf_freelist);
sf_base = kmem_alloc_pageable(kernel_map, nsfbufs * PAGE_SIZE);
sf_bufs = malloc(nsfbufs * sizeof(struct sf_buf), M_TEMP, M_NOWAIT);
@@ -1335,6 +1345,7 @@ sf_buf_init(void *arg)
sf_bufs[i].kva = sf_base + i * PAGE_SIZE;
SLIST_INSERT_HEAD(&sf_freelist, &sf_bufs[i], free_list);
}
+ mtx_exit(&sf_freelist.sf_lock, MTX_DEF);
}
/*
@@ -1344,25 +1355,21 @@ static struct sf_buf *
sf_buf_alloc()
{
struct sf_buf *sf;
- int s;
- s = splimp();
+ mtx_enter(&sf_freelist.sf_lock, MTX_DEF);
while ((sf = SLIST_FIRST(&sf_freelist)) == NULL) {
sf_buf_alloc_want = 1;
- tsleep(&sf_freelist, PVM, "sfbufa", 0);
+ msleep(&sf_freelist, &sf_freelist.sf_lock, PVM, "sfbufa", 0);
}
SLIST_REMOVE_HEAD(&sf_freelist, free_list);
- splx(s);
+ mtx_exit(&sf_freelist.sf_lock, MTX_DEF);
return (sf);
}
#define dtosf(x) (&sf_bufs[((uintptr_t)(x) - (uintptr_t)sf_base) >> PAGE_SHIFT])
/*
- *
* Detatch mapped page and release resources back to the system.
- *
- * Must be called at splimp.
*/
static void
sf_buf_free(caddr_t addr, void *args)
@@ -1385,15 +1392,17 @@ sf_buf_free(caddr_t addr, void *args)
vm_page_free(m);
splx(s);
sf->m = NULL;
+ mtx_enter(&sf_freelist.sf_lock, MTX_DEF);
SLIST_INSERT_HEAD(&sf_freelist, sf, free_list);
if (sf_buf_alloc_want) {
sf_buf_alloc_want = 0;
wakeup(&sf_freelist);
}
+ mtx_exit(&sf_freelist.sf_lock, MTX_DEF);
}
/*
- * sendfile(2).
+ * sendfile(2)
* int sendfile(int fd, int s, off_t offset, size_t nbytes,
* struct sf_hdtr *hdtr, off_t *sbytes, int flags)
*
OpenPOWER on IntegriCloud