Re: need better POSIX semaphore support

From: Kostik Belousov <kostikbel_at_gmail.com>
Date: Tue, 1 Jun 2010 20:05:26 +0300
On Tue, Jun 01, 2010 at 11:41:09AM -0400, John Baldwin wrote:
> On Sunday 30 May 2010 11:06:22 am Kostik Belousov wrote:
> > On Sun, May 30, 2010 at 06:30:35PM +0400, Dmitry Marakasov wrote:
> > > Hi!
> > > 
> > > Not long ago, POSIX semaphores support was enabled by default as it's
> > > becoming more widely used, by e.g. firefox. However, the support
> > > for these is still incomplete: we only have systemwide limit of 30
> > > semaphores, and that doesn't seem to be configurable neither online with
> > > sysctl, nor at boottime from loader.conf. I only was able to raise
> > > semaphore count by changing SEM_MAX in kernel sources.
> > > 
> > > The real appliaction which needs more semaphores is lightspark
> > > (graphics/lightspark-devel) flash plugin - it uses ~40 sems for simple
> > > clips and ~250 for something like youtube videos.
> > > 
> > > Until there more apps that require proper semaphore support, I guess
> > > we need to improve it asap. Given the amount of memory used by ksem,
> > > the least can be done is SEM_MAX bumped up to 5120 or so for
> > > non-embedded kernels. 5120 semaphores require just 644k of kernel
> > > memory (judging by vmstat), and is "ought to be enough for anybody".
> > > Another good thing would be to make it configurable at boot-time
> > > or even better in runtime.
> > 
> > HEAD contains different implementation. Apparently, it did not made
> > into stable/8 yet, so it will not appear in the 8.1.
> 
> The one thing I don't like about this approach is you can write the
> variable even when sem.ko isn't loaded. The SEM_* values should really
> only exist when sem.ko is loaded I think, which requires moving them
> into uipc_sem.c.

I think the values should exist always, because sysconf(3) returns
error (i.e. -1 and errno set) when sysctl fails. sysconf(3) interprets
0 result as "feature not supported".

I modified the patch to only allow change of value when the module is loaded.
Also, the module unload now clears mib. As usual, module unload races are
not handled.

diff --git a/sys/kern/posix4_mib.c b/sys/kern/posix4_mib.c
index 5242b31..cbe140d 100644
--- a/sys/kern/posix4_mib.c
+++ b/sys/kern/posix4_mib.c
_at__at_ -45,6 +45,8 _at__at_ __FBSDID("$FreeBSD$");
 static int facility[CTL_P1003_1B_MAXID - 1];
 static int facility_initialized[CTL_P1003_1B_MAXID - 1];
 
+static int p31b_sysctl_proc(SYSCTL_HANDLER_ARGS);
+
 /* OID_AUTO isn't working with sysconf(3).  I guess I'd have to
  * modify it to do a lookup by name from the index.
  * For now I've left it a top-level sysctl.
_at__at_ -55,16 +57,21 _at__at_ static int facility_initialized[CTL_P1003_1B_MAXID - 1];
 SYSCTL_DECL(_p1003_1b);
 
 #define P1B_SYSCTL(num, name)  \
-SYSCTL_INT(_p1003_1b, num, \
-	name, CTLFLAG_RD, facility + num - 1, 0, "");
+	SYSCTL_INT(_p1003_1b, num, name, CTLFLAG_RD, facility + num - 1, 0, "");
+#define P1B_SYSCTL_RW(num, name)  \
+	SYSCTL_PROC(_p1003_1b, num, name, CTLTYPE_INT | CTLFLAG_RW, NULL, num, \
+	    p31b_sysctl_proc, "I", "");
 
 #else
 
 SYSCTL_DECL(_kern_p1003_1b);
 
 #define P1B_SYSCTL(num, name)  \
-SYSCTL_INT(_kern_p1003_1b, OID_AUTO, \
-	name, CTLFLAG_RD, facility + num - 1, 0, "");
+	SYSCTL_INT(_kern_p1003_1b, OID_AUTO, name, CTLFLAG_RD, \
+	    facility + num - 1, 0, "");
+#define P1B_SYSCTL_RW(num, name)  \
+	SYSCTL_PROC(_p1003_1b, OID_AUTO, name, CTLTYPE_INT | CTLFLAG_RW, NULL, \
+	    num, p31b_sysctl_proc, "I", "");
 SYSCTL_NODE(_kern, OID_AUTO, p1003_1b, CTLFLAG_RW, 0, "P1003.1B");
 
 #endif
_at__at_ -91,13 +98,28 _at__at_ P1B_SYSCTL(CTL_P1003_1B_DELAYTIMER_MAX, delaytimer_max);
 P1B_SYSCTL(CTL_P1003_1B_MQ_OPEN_MAX, mq_open_max);
 P1B_SYSCTL(CTL_P1003_1B_PAGESIZE, pagesize);
 P1B_SYSCTL(CTL_P1003_1B_RTSIG_MAX, rtsig_max);
-P1B_SYSCTL(CTL_P1003_1B_SEM_NSEMS_MAX, sem_nsems_max);
+P1B_SYSCTL_RW(CTL_P1003_1B_SEM_NSEMS_MAX, sem_nsems_max);
 P1B_SYSCTL(CTL_P1003_1B_SEM_VALUE_MAX, sem_value_max);
 P1B_SYSCTL(CTL_P1003_1B_SIGQUEUE_MAX, sigqueue_max);
 P1B_SYSCTL(CTL_P1003_1B_TIMER_MAX, timer_max);
 
 #define P31B_VALID(num)	((num) >= 1 && (num) < CTL_P1003_1B_MAXID)
 
+static int
+p31b_sysctl_proc(SYSCTL_HANDLER_ARGS)
+{
+	int error, num, val;
+
+	num = arg2;
+	if (!P31B_VALID(num))
+		return (EINVAL);
+	val = facility_initialized[num] ? facility[num - 1] : 0;
+	error = sysctl_handle_int(oidp, &val, 0, req);
+	if (error == 0 && req->newptr != NULL && facility_initialized[num])
+		facility[num - 1] = val;
+	return (error);
+}
+
 /* p31b_setcfg: Set the configuration
  */
 void
_at__at_ -110,6 +132,14 _at__at_ p31b_setcfg(int num, int value)
 	}
 }
 
+void
+p31b_unsetcfg(int num)
+{
+
+	facility[num - 1] = 0;
+	facility_initialized[num -1] = 0;
+}
+
 int
 p31b_getcfg(int num)
 {
diff --git a/sys/kern/uipc_sem.c b/sys/kern/uipc_sem.c
index d9229ea..0b8f132 100644
--- a/sys/kern/uipc_sem.c
+++ b/sys/kern/uipc_sem.c
_at__at_ -976,6 +976,8 _at__at_ ksem_module_destroy(void)
 	sx_destroy(&ksem_dict_lock);
 	mtx_destroy(&ksem_count_lock);
 	mtx_destroy(&sem_lock);
+	p31b_unsetcfg(CTL_P1003_1B_SEM_VALUE_MAX);
+	p31b_unsetcfg(CTL_P1003_1B_SEM_NSEMS_MAX);
 }
 
 static int
diff --git a/sys/sys/posix4.h b/sys/sys/posix4.h
index ea379c0..34f77f4 100644
--- a/sys/sys/posix4.h
+++ b/sys/sys/posix4.h
_at__at_ -64,6 +64,7 _at__at_ int p31b_proc(struct proc *, pid_t, struct proc **);
 void p31b_setcfg(int, int);
 int p31b_getcfg(int);
 int p31b_iscfg(int);
+void p31b_unsetcfg(int);
 
 #ifdef _KPOSIX_PRIORITY_SCHEDULING
 

Received on Tue Jun 01 2010 - 15:05:32 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:40:04 UTC