need better POSIX semaphore support
Kostik Belousov
kostikbel at gmail.com
Tue Jun 1 17:05:32 UTC 2010
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
@@ -45,6 +45,8 @@ __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.
@@ -55,16 +57,21 @@ 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
@@ -91,13 +98,28 @@ 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
@@ -110,6 +132,14 @@ 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
@@ -976,6 +976,8 @@ 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
@@ -64,6 +64,7 @@ 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
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 196 bytes
Desc: not available
Url : http://lists.freebsd.org/pipermail/freebsd-stable/attachments/20100601/ddebd5c0/attachment.pgp
More information about the freebsd-stable
mailing list