tech-kern archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: lwp resource limit
christos%zoulas.com@localhost (Christos Zoulas) wrote:
> Hello,
>
> This is a new resource limit to prevent users from exhausting kernel
> resources that lwps use.
>
> ...
>
> comments?
>
Few comments on the patch:
> Index: kern/init_main.c
> ===================================================================
> RCS file: /cvsroot/src/sys/kern/init_main.c,v
> retrieving revision 1.442
> diff -u -p -u -r1.442 init_main.c
> --- kern/init_main.c 19 Feb 2012 21:06:47 -0000 1.442
> +++ kern/init_main.c 23 May 2012 23:19:31 -0000
> @@ -256,6 +256,7 @@ int cold = 1; /* still
> working on star struct timespec boottime; /* time at
> system startup - will only follow settime deltas */
> int start_init_exec; /* semaphore for start_init()
> */ +int maxlwp;
>
maxlwp should be __read_mostly. However, why is it (and all sysctls)
in init_main.c? I suppose you just followed current way (just historic
code), but I think it is a bad practice. We should move such globals,
as well as sysctls, to the modules they belong to and make them static.
In this case it would be kern_lwp.c module.
> @@ -291,6 +292,12 @@ main(void)
> #endif
> l->l_pflag |= LP_RUNNING;
>
> +#ifdef __HAVE_CPU_MAXLWP
> + maxlwp = cpu_maxlwp();
> +#else
> + maxlwp = 1024;
> +#endif
> +
1024 seems to small for me. How about 2048 (if not 4096)? Please make
it a #define somewhere (perhaps lwp.h?). When would the MD code override
the value?
> + if (nmaxlwp < 0 || nmaxlwp >= 65536)
> + return EINVAL;
> +#ifdef __HAVE_CPU_MAXLWP
> + if (nmaxlwp > cpu_maxlwp())
> + return EINVAL;
> +#endif
> + maxlwp = nmaxlwp;
If there are MD limitations, I tend to think that we should restructure
the code a little and allow lwp_create() to fail..
> int
> lwp_create(lwp_t *l1, proc_t *p2, vaddr_t uaddr, int flags,
> void *stack, size_t stacksize, void (*func)(void *), void
> *arg,
> - lwp_t **rnewlwpp, int sclass)
> + lwp_t **rnewlwpp, int sclass, int enforce)
> {
Variable 'enforce' should bool, but do we really need it? We can know
whether it is a first LWP i.e. fork() call or creation of kthread from
inside. Also, why not to account simple processes? fork() is still a
creation of LWP. Do you know how QNX accounts this?
For allowing process creation when maxlwp limit is exhausted, I would
say this problem is better solved with maxprocperuid you mentioned.
> + uid = kauth_cred_getuid(l1->l_cred);
> + count = chglwpcnt(uid, 1);
There is no need to perform chglwpcnt(), which has a cost of atomic
operation, if we are not checking against the limit (kthread case).
> +
> + int nlwps = p->p_nlwps;
> + (void)chglwpcnt(kauth_cred_getuid(ncred), -nlwps);
> + (void)chglwpcnt(r, nlwps);
> +
You need to acquire p->p_lock around this. I suppose this is the
"atomicity issue" mentioned above. :)
> @@ -805,6 +807,7 @@ lwp_exit_switchaway(lwp_t *l)
> LOCKDEBUG_BARRIER(NULL, 0);
>
> kstack_check_magic(l);
> + chglwpcnt(kauth_cred_geteuid(l->l_cred), -1);
>
Since this was done in lwp_exit(), why again?
> +#define _MEM(n) { # n, offsetof(struct uidinfo, ui_ ## n) }
> + _MEM(proccnt),
> + _MEM(lwpcnt),
> + _MEM(lockcnt),
> + _MEM(sbsize),
> +#undef _MEM
I would avoid macro, it is only four entries. :)
> + node.sysctl_data = &cnt;
> + uip = uid_find(kauth_cred_geteuid(l->l_cred));
> +
> + *(uint64_t *)node.sysctl_data =
> + *(u_long *)((char *)uip + nv[i].value);
Potentially unaligned access? Use memcpy()?
> Index: sys/sysctl.h
> ===================================================================
> RCS file: /cvsroot/src/sys/sys/sysctl.h,v
> retrieving revision 1.199
> diff -u -p -u -r1.199 sysctl.h
> --- sys/sysctl.h 27 Jan 2012 19:48:41 -0000 1.199
> +++ sys/sysctl.h 23 May 2012 23:19:36 -0000
> @@ -266,7 +266,8 @@ struct ctlname {
> #define KERN_SYSVIPC 82 /* node: SysV IPC
> #parameters */ define KERN_BOOTTIME 83 /*
> #struct: time kernel was booted */ define
> #KERN_EVCNT 84 /* struct: evcnts */
> -#define KERN_MAXID 85 /* number of valid
> kern ids */ +#define KERN_MAXLWP 85 /* int:
> maxlwp */ +#define KERN_MAXID 86 /* number
> of valid kern ids */
Use CTL_CREATE instead of static entry (KERN_MAXLWP)? I thought we are
trying to convert everything to dynamic creation/lookup and not add more
hardcoded sysctl nodes.
--
Mindaugas
Home |
Main Index |
Thread Index |
Old Index