Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 22 Sep 2012 12:27:50 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org
Subject:   svn commit: r240814 - in stable/9/sys: kern sys
Message-ID:  <201209221227.q8MCRohF065762@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Sat Sep 22 12:27:50 2012
New Revision: 240814
URL: http://svn.freebsd.org/changeset/base/240814

Log:
  MFC r237431:
  Enchance the shared page chunk allocator.

Modified:
  stable/9/sys/kern/kern_exec.c
  stable/9/sys/sys/sysent.h
Directory Properties:
  stable/9/sys/   (props changed)

Modified: stable/9/sys/kern/kern_exec.c
==============================================================================
--- stable/9/sys/kern/kern_exec.c	Sat Sep 22 12:17:09 2012	(r240813)
+++ stable/9/sys/kern/kern_exec.c	Sat Sep 22 12:27:50 2012	(r240814)
@@ -1514,33 +1514,81 @@ exec_unregister(execsw_arg)
 	return (0);
 }
 
+static struct sx shared_page_alloc_sx;
 static vm_object_t shared_page_obj;
 static int shared_page_free;
 
-int
-shared_page_fill(int size, int align, const char *data)
+struct sf_buf *
+shared_page_write_start(int base)
 {
 	vm_page_t m;
 	struct sf_buf *s;
+
+	VM_OBJECT_LOCK(shared_page_obj);
+	m = vm_page_grab(shared_page_obj, OFF_TO_IDX(base), VM_ALLOC_RETRY);
+	VM_OBJECT_UNLOCK(shared_page_obj);
+	s = sf_buf_alloc(m, SFB_DEFAULT);
+	return (s);
+}
+
+void
+shared_page_write_end(struct sf_buf *sf)
+{
+	vm_page_t m;
+
+	m = sf_buf_page(sf);
+	sf_buf_free(sf);
+	VM_OBJECT_LOCK(shared_page_obj);
+	vm_page_wakeup(m);
+	VM_OBJECT_UNLOCK(shared_page_obj);
+}
+
+void
+shared_page_write(int base, int size, const void *data)
+{
+	struct sf_buf *sf;
 	vm_offset_t sk;
+
+	sf = shared_page_write_start(base);
+	sk = sf_buf_kva(sf);
+	bcopy(data, (void *)(sk + (base & PAGE_MASK)), size);
+	shared_page_write_end(sf);
+}
+
+static int
+shared_page_alloc_locked(int size, int align)
+{
 	int res;
 
-	VM_OBJECT_LOCK(shared_page_obj);
-	m = vm_page_grab(shared_page_obj, 0, VM_ALLOC_RETRY);
 	res = roundup(shared_page_free, align);
 	if (res + size >= IDX_TO_OFF(shared_page_obj->size))
 		res = -1;
-	else {
-		VM_OBJECT_UNLOCK(shared_page_obj);
-		s = sf_buf_alloc(m, SFB_DEFAULT);
-		sk = sf_buf_kva(s);
-		bcopy(data, (void *)(sk + res), size);
+	else
 		shared_page_free = res + size;
-		sf_buf_free(s);
-		VM_OBJECT_LOCK(shared_page_obj);
-	}
-	vm_page_wakeup(m);
-	VM_OBJECT_UNLOCK(shared_page_obj);
+	return (res);
+}
+
+int
+shared_page_alloc(int size, int align)
+{
+	int res;
+
+	sx_xlock(&shared_page_alloc_sx);
+	res = shared_page_alloc_locked(size, align);
+	sx_xunlock(&shared_page_alloc_sx);
+	return (res);
+}
+
+int
+shared_page_fill(int size, int align, const void *data)
+{
+	int res;
+
+	sx_xlock(&shared_page_alloc_sx);
+	res = shared_page_alloc_locked(size, align);
+	if (res != -1)
+		shared_page_write(res, size, data);
+	sx_xunlock(&shared_page_alloc_sx);
 	return (res);
 }
 
@@ -1549,6 +1597,7 @@ shared_page_init(void *dummy __unused)
 {
 	vm_page_t m;
 
+	sx_init(&shared_page_alloc_sx, "shpsx");
 	shared_page_obj = vm_pager_allocate(OBJT_PHYS, 0, PAGE_SIZE,
 	    VM_PROT_DEFAULT, 0, NULL);
 	VM_OBJECT_LOCK(shared_page_obj);

Modified: stable/9/sys/sys/sysent.h
==============================================================================
--- stable/9/sys/sys/sysent.h	Sat Sep 22 12:17:09 2012	(r240813)
+++ stable/9/sys/sys/sysent.h	Sat Sep 22 12:27:50 2012	(r240814)
@@ -256,8 +256,13 @@ int	lkmressys(struct thread *, struct no
 int	syscall_thread_enter(struct thread *td, struct sysent *se);
 void	syscall_thread_exit(struct thread *td, struct sysent *se);
 
-int shared_page_fill(int size, int align, const char *data);
+struct sf_buf;
+int shared_page_alloc(int size, int align);
+int shared_page_fill(int size, int align, const void *data);
+void shared_page_write(int base, int size, const void *data);
 void exec_sysvec_init(void *param);
+struct sf_buf *shared_page_write_start(int base);
+void shared_page_write_end(struct sf_buf *sf);
 
 #define INIT_SYSENTVEC(name, sv)					\
     SYSINIT(name, SI_SUB_EXEC, SI_ORDER_ANY,				\



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201209221227.q8MCRohF065762>