Re: lwp resource limit

2012-06-13 Thread Mindaugas Rasiukevicius
Matt Thomas m...@3am-software.com wrote:
 
 On Jun 12, 2012, at 8:26 PM, Christos Zoulas wrote:
 
  On Jun 13,  2:15am, y...@mwd.biglobe.ne.jp (YAMAMOTO Takashi) wrote:
  -- Subject: Re: lwp resource limit
  
  |  Can you explain what you mean by api incompatible? It is used in
  |  getrlimit the same way we use it, how can it be different?
  | 
  | it's semantics (what's counted for) is different, isn't it?
  
  I don't know, the pages I looked don't offer details.
 
 The nice thing about our semantics is you can disable threaded programs
 by setting lwp count to 0 but still allow non-threaded programs to run.

Yes, but that is not the point.  I think what yamt means is that we should
check whether our approach (i.e. the way accounting is done) is compatible
with QNX and if not, then either rename the limit or make it compatible.

Would somebody be able to check?  Sean?

-- 
Mindaugas


Re: lwp resource limit

2012-06-13 Thread Matt Thomas

On Jun 13, 2012, at 4:27 AM, Mindaugas Rasiukevicius wrote:

 Matt Thomas m...@3am-software.com wrote:
 
 On Jun 12, 2012, at 8:26 PM, Christos Zoulas wrote:
 
 On Jun 13,  2:15am, y...@mwd.biglobe.ne.jp (YAMAMOTO Takashi) wrote:
 -- Subject: Re: lwp resource limit
 
 |  Can you explain what you mean by api incompatible? It is used in
 |  getrlimit the same way we use it, how can it be different?
 | 
 | it's semantics (what's counted for) is different, isn't it?
 
 I don't know, the pages I looked don't offer details.
 
 The nice thing about our semantics is you can disable threaded programs
 by setting lwp count to 0 but still allow non-threaded programs to run.
 
 Yes, but that is not the point.  I think what yamt means is that we should
 check whether our approach (i.e. the way accounting is done) is compatible
 with QNX and if not, then either rename the limit or make it compatible.
 
 Would somebody be able to check?  Sean?

Looking at QNX docs, it seems that exceeding 
RLIMIT_NTHR causes attempts to create threads 
(e.g. by calling pthread_create()) fails.

Interesting that RLIMIT_NTHR seems to be per-process.


Re: lwp resource limit

2012-06-13 Thread Christos Zoulas
In article e47bb11a-cbd1-4b67-8bfb-ae701890b...@3am-software.com,
Matt Thomas  m...@3am-software.com wrote:

Looking at QNX docs, it seems that exceeding 
RLIMIT_NTHR causes attempts to create threads 
(e.g. by calling pthread_create()) fails.

Interesting that RLIMIT_NTHR seems to be per-process.

simpler to implement that way :-)

christos




Re: lwp resource limit

2012-06-12 Thread YAMAMOTO Takashi
hi,

 On Jun 12,  2:46am, y...@mwd.biglobe.ne.jp (YAMAMOTO Takashi) wrote:
 -- Subject: Re: lwp resource limit
 
 |  
 https://bdsc.webapps.blackberry.com/native/reference/com.qnx.doc.neutrino.lib_ref/topic/g/getrlimit.html
 | 
 | if it's incompatible (i don't know), there's no reason to use
 | an inconsistent name.
 
 Can you explain what you mean by api incompatible? It is used in getrlimit the
 same way we use it, how can it be different?

it's semantics (what's counted for) is different, isn't it?

YAMAMOTO Takashi

 
 christos


Re: lwp resource limit

2012-06-12 Thread Christos Zoulas
On Jun 13,  2:15am, y...@mwd.biglobe.ne.jp (YAMAMOTO Takashi) wrote:
-- Subject: Re: lwp resource limit

|  Can you explain what you mean by api incompatible? It is used in getrlimit 
the
|  same way we use it, how can it be different?
| 
| it's semantics (what's counted for) is different, isn't it?

I don't know, the pages I looked don't offer details.

christos


Re: lwp resource limit

2012-06-12 Thread Matt Thomas

On Jun 12, 2012, at 8:26 PM, Christos Zoulas wrote:

 On Jun 13,  2:15am, y...@mwd.biglobe.ne.jp (YAMAMOTO Takashi) wrote:
 -- Subject: Re: lwp resource limit
 
 |  Can you explain what you mean by api incompatible? It is used in 
 getrlimit the
 |  same way we use it, how can it be different?
 | 
 | it's semantics (what's counted for) is different, isn't it?
 
 I don't know, the pages I looked don't offer details.

The nice thing about our semantics is you can disable threaded programs
by setting lwp count to 0 but still allow non-threaded programs to run.

Re: lwp resource limit

2012-06-11 Thread YAMAMOTO Takashi
hi,

 On May 24,  6:55am, y...@mwd.biglobe.ne.jp (YAMAMOTO Takashi) wrote:
 -- Subject: Re: lwp resource limit
 
 | hi,
 | 
 |  Hello,
 |  
 |  This is a new resource limit to prevent users from exhausting kernel
 |  resources that lwps use.
 |  
 |  - The limit is per uid
 |  - The default is 1024 per user unless the architecture overrides it
 |  - The kernel is never prohibited from creating threads
 |  - Exceeding the thread limit does not prevent process creation, but
 |it will prevent processes from creating additional threads. So the
 |effective thread limit is nlwp + nproc
 |  - The name NTHR was chosen to follow prior art
 | 
 | can you provide a pointer to the prior art?
 | is it API compatible?
 
 https://bdsc.webapps.blackberry.com/native/reference/com.qnx.doc.neutrino.lib_ref/topic/g/getrlimit.html

if it's incompatible (i don't know), there's no reason to use
an inconsistent name.

YAMAMOTO Takashi

 
 christos


Re: lwp resource limit

2012-06-11 Thread Christos Zoulas
On Jun 12,  2:46am, y...@mwd.biglobe.ne.jp (YAMAMOTO Takashi) wrote:
-- Subject: Re: lwp resource limit

|  
https://bdsc.webapps.blackberry.com/native/reference/com.qnx.doc.neutrino.lib_ref/topic/g/getrlimit.html
| 
| if it's incompatible (i don't know), there's no reason to use
| an inconsistent name.

Can you explain what you mean by api incompatible? It is used in getrlimit the
same way we use it, how can it be different?

christos


Re: lwp resource limit

2012-06-08 Thread Matt Thomas

On Jun 7, 2012, at 7:31 PM, Christos Zoulas wrote:

 New version addressing most of the issues:
 
http://www.netbsd.org/~christos/maxlwp.diff
 
 If I don't hear any objections I will commit it over the weekend, and
 then I am going to start working on amending the documentation and
 resource users (shells etc.)

lwp_create int enforce should be bool and we should pass true/false.

+   if (l-l_flag  LW_RESCOUNT)

I don't see the need for this, why not check p_nlwp == 1?

if this is the first lwp for the proc p_nlwp should be 0 so check
maxproc otherwise maxlwp.


Re: lwp resource limit

2012-06-08 Thread Matt Thomas

On Jun 8, 2012, at 5:24 AM, Christos Zoulas wrote:

 +if (l-l_flag  LW_RESCOUNT)
 
 I don't see the need for this, why not check p_nlwp == 1?
 
 if this is the first lwp for the proc p_nlwp should be 0 so check
 maxproc otherwise maxlwp.
 
 You are forgetting compat_linux.

No I'm not.  I'm not using l_lid but the # of lwps in the proc.



Re: lwp resource limit

2012-06-08 Thread Christos Zoulas
On Jun 8,  9:00am, m...@3am-software.com (Matt Thomas) wrote:
-- Subject: Re: lwp resource limit

| 
| On Jun 8, 2012, at 5:24 AM, Christos Zoulas wrote:
| 
|  +  if (l-l_flag  LW_RESCOUNT)
|  
|  I don't see the need for this, why not check p_nlwp == 1?
|  
|  if this is the first lwp for the proc p_nlwp should be 0 so check
|  maxproc otherwise maxlwp.
|  
|  You are forgetting compat_linux.
| 
| No I'm not.  I'm not using l_lid but the # of lwps in the proc.

I made the change, but now this begs the question to remove the enforce
argument because I don't like the assymmetry. Should I do that too? And
ignore kthreads in using a different criterion?

christos


Re: lwp resource limit

2012-06-08 Thread Matt Thomas

On Jun 8, 2012, at 9:19 AM, Christos Zoulas wrote:

 On Jun 8,  9:00am, m...@3am-software.com (Matt Thomas) wrote:
 -- Subject: Re: lwp resource limit
 
 | 
 | On Jun 8, 2012, at 5:24 AM, Christos Zoulas wrote:
 | 
 |  +if (l-l_flag  LW_RESCOUNT)
 |  
 |  I don't see the need for this, why not check p_nlwp == 1?
 |  
 |  if this is the first lwp for the proc p_nlwp should be 0 so check
 |  maxproc otherwise maxlwp.
 |  
 |  You are forgetting compat_linux.
 | 
 | No I'm not.  I'm not using l_lid but the # of lwps in the proc.
 
 I made the change, but now this begs the question to remove the enforce
 argument because I don't like the assymmetry. Should I do that too? And
 ignore kthreads in using a different criterion?

LW_SYSTEM/LW_INTR threads shouldn't be counted


Re: lwp resource limit

2012-06-08 Thread Christos Zoulas
In article a4f96b90-d2e7-4f98-9b44-a040ded32...@3am-software.com,
Matt Thomas  m...@3am-software.com wrote:

On Jun 8, 2012, at 9:19 AM, Christos Zoulas wrote:

 On Jun 8,  9:00am, m...@3am-software.com (Matt Thomas) wrote:
 -- Subject: Re: lwp resource limit
 
 | 
 | On Jun 8, 2012, at 5:24 AM, Christos Zoulas wrote:
 | 
 |  +   if (l-l_flag  LW_RESCOUNT)
 |  
 |  I don't see the need for this, why not check p_nlwp == 1?
 |  
 |  if this is the first lwp for the proc p_nlwp should be 0 so check
 |  maxproc otherwise maxlwp.
 |  
 |  You are forgetting compat_linux.
 | 
 | No I'm not.  I'm not using l_lid but the # of lwps in the proc.
 
 I made the change, but now this begs the question to remove the enforce
 argument because I don't like the assymmetry. Should I do that too? And
 ignore kthreads in using a different criterion?

LW_SYSTEM/LW_INTR threads shouldn't be counted

New diff in http://www.netbsd.org/~christos/maxlwp.diff

christos




Re: lwp resource limit

2012-06-08 Thread Matt Thomas

On Jun 8, 2012, at 1:04 PM, Christos Zoulas wrote:

 In article a4f96b90-d2e7-4f98-9b44-a040ded32...@3am-software.com,
 Matt Thomas  m...@3am-software.com wrote:
 
 On Jun 8, 2012, at 9:19 AM, Christos Zoulas wrote:
 
 On Jun 8,  9:00am, m...@3am-software.com (Matt Thomas) wrote:
 -- Subject: Re: lwp resource limit
 
 | 
 | On Jun 8, 2012, at 5:24 AM, Christos Zoulas wrote:
 | 
 |  +  if (l-l_flag  LW_RESCOUNT)
 |  
 |  I don't see the need for this, why not check p_nlwp == 1?
 |  
 |  if this is the first lwp for the proc p_nlwp should be 0 so check
 |  maxproc otherwise maxlwp.
 |  
 |  You are forgetting compat_linux.
 | 
 | No I'm not.  I'm not using l_lid but the # of lwps in the proc.
 
 I made the change, but now this begs the question to remove the enforce
 argument because I don't like the assymmetry. Should I do that too? And
 ignore kthreads in using a different criterion?
 
 LW_SYSTEM/LW_INTR threads shouldn't be counted
 
 New diff in http://www.netbsd.org/~christos/maxlwp.diff

Better.

Rather than have all the #ifdef __HAVE_CPU_MAXLWP how about doing

#ifndef __HAVE_CPU_MAXLWP
static inline int
cpu_maxlwp(void)
{
return maxlwp;
}
#endif

in an appropriate header file?




Re: lwp resource limit

2012-06-08 Thread Matt Thomas

On Jun 8, 2012, at 4:47 PM, Matt Thomas wrote:
 
 Rather than have all the #ifdef __HAVE_CPU_MAXLWP how about doing
 
 #ifndef __HAVE_CPU_MAXLWP
 static inline int
 cpu_maxlwp(void)
 {
   return maxlwp;
 }
 #endif
 
 in an appropriate header file?

Or maybe

static inline int
cpu_maxlwp(int new_maxlwp)
{
return new_maxlwp;
}

So that maxlwp can be made static to kern_lwp.c


Re: lwp resource limit

2012-06-08 Thread Christos Zoulas
On Jun 8,  4:47pm, m...@3am-software.com (Matt Thomas) wrote:
-- Subject: Re: lwp resource limit

| 
| On Jun 8, 2012, at 1:04 PM, Christos Zoulas wrote:
| 
|  In article a4f96b90-d2e7-4f98-9b44-a040ded32...@3am-software.com,
|  Matt Thomas  m...@3am-software.com wrote:
|  
|  On Jun 8, 2012, at 9:19 AM, Christos Zoulas wrote:
|  
|  On Jun 8,  9:00am, m...@3am-software.com (Matt Thomas) wrote:
|  -- Subject: Re: lwp resource limit
|  
|  | 
|  | On Jun 8, 2012, at 5:24 AM, Christos Zoulas wrote:
|  | 
|  |  +if (l-l_flag  LW_RESCOUNT)
|  |  
|  |  I don't see the need for this, why not check p_nlwp == 1?
|  |  
|  |  if this is the first lwp for the proc p_nlwp should be 0 so check
|  |  maxproc otherwise maxlwp.
|  |  
|  |  You are forgetting compat_linux.
|  | 
|  | No I'm not.  I'm not using l_lid but the # of lwps in the proc.
|  
|  I made the change, but now this begs the question to remove the enforce
|  argument because I don't like the assymmetry. Should I do that too? And
|  ignore kthreads in using a different criterion?
|  
|  LW_SYSTEM/LW_INTR threads shouldn't be counted
|  
|  New diff in http://www.netbsd.org/~christos/maxlwp.diff
| 
| Better.
| 
| Rather than have all the #ifdef __HAVE_CPU_MAXLWP how about doing
| 
| #ifndef __HAVE_CPU_MAXLWP
| static inline int
| cpu_maxlwp(void)
| {
|   return maxlwp;
| }
| #endif
| 
| in an appropriate header file?

Ok.

christos


Re: lwp resource limit

2012-06-08 Thread Christos Zoulas
On Jun 8,  5:10pm, m...@3am-software.com (Matt Thomas) wrote:
-- Subject: Re: lwp resource limit

| 
| On Jun 8, 2012, at 4:47 PM, Matt Thomas wrote:
|  
|  Rather than have all the #ifdef __HAVE_CPU_MAXLWP how about doing
|  
|  #ifndef __HAVE_CPU_MAXLWP
|  static inline int
|  cpu_maxlwp(void)
|  {
|  return maxlwp;
|  }
|  #endif
|  
|  in an appropriate header file?
| 
| Or maybe
| 
| static inline int
| cpu_maxlwp(int new_maxlwp)
| {
|   return new_maxlwp;
| }
| 
| So that maxlwp can be made static to kern_lwp.c

And what is new_maxlwp?

christos


Re: lwp resource limit

2012-06-08 Thread Christos Zoulas
On Jun 8,  6:22pm, m...@3am-software.com (Matt Thomas) wrote:
-- Subject: Re: lwp resource limit

| Hmmm, I think maxlwp should go in param.c and there should a MAXLWP.

Ok, new diff

http://www.netbsd.org/~christos/maxlwp.diff

christos


Re: lwp resource limit

2012-06-07 Thread Christos Zoulas
New version addressing most of the issues:

http://www.netbsd.org/~christos/maxlwp.diff

If I don't hear any objections I will commit it over the weekend, and
then I am going to start working on amending the documentation and
resource users (shells etc.)

christos



Re: lwp resource limit

2012-06-05 Thread Matt Thomas

On Jun 4, 2012, at 7:19 PM, Christos Zoulas wrote:

 In article 20120605013242.ga7...@panix.com,
 Thor Lancelot Simon  t...@panix.com wrote:
 On Mon, Jun 04, 2012 at 06:13:09PM -0400, Christos Zoulas wrote:
 
 That is a good idea! The only problem with it is that ps -sx and the sysctl
 limit will not match (the limit will be lower than the sysctl number by the
 number of processes). It does have the nice property though that the process
 gets created anyway, as it is now (counting the limit).
 
 It is a very simple change, and if people prefer it, I will do it.
 
 I think it's truly elegant.  Do it!
 
 I'll need to burn a bit in the lwp flags to indicate that exit should not
 decrease the count, or hardcode not to do it for lid == 1. Which one do
 you prefer?

The latter is my preference.  How many processes ever have lid 1 exit early?

Re: lwp resource limit

2012-06-05 Thread Martin Husemann
On Mon, Jun 04, 2012 at 11:16:45PM -0700, Matt Thomas wrote:
 The latter is my preference.  How many processes ever have lid 1 exit early?

Yes, do not count lid 1 and don't have it decrement the count on exit.

Martin


Re: lwp resource limit

2012-06-05 Thread Chuck Silvers
On Tue, Jun 05, 2012 at 11:20:35AM +0200, Martin Husemann wrote:
 On Mon, Jun 04, 2012 at 11:16:45PM -0700, Matt Thomas wrote:
  The latter is my preference.  How many processes ever have lid 1 exit early?
 
 Yes, do not count lid 1 and don't have it decrement the count on exit.

some processes (ie. emul_linux ones) do not have a lid 1, so this won't work.
can't you just not change the count for the last lwp in a process?

-Chuck


Re: lwp resource limit

2012-06-04 Thread Christos Zoulas
In article 20120603194407.72f5514a...@mail.netbsd.org,
Mindaugas Rasiukevicius  rm...@netbsd.org wrote:

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.

Yes, ok. I'll make that change.

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?

I just followed the pattern with maxproc. I will bump the limit, but I
think that putting in the header is a mistake because things might use
the constant thinking that it always represents reality.

If there are MD limitations, I tend to think that we should restructure
the code a little and allow lwp_create() to fail..

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?

The problem I had was that it is too late to fail the lwp_create() call
inside the fork() code. I don't know how QNX accounts for it, but one
way to fix the problem is to check and increment the lwp limit at the
same place that the proc limit is incremented and fail then. I will
do that instead.

For allowing process creation when maxlwp limit is exhausted, I would
say this problem is better solved with maxprocperuid you mentioned.

Yes, perhaps. I think that the process/lwp limits need to be re-thought.


 +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).

Ok, I can fix that if it is performance critical, but is it? In reality
how frequently do we create kernel threads, and is this the place where
we spend most of our time? I'd rather not make the code more complicated.

 +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. :)

Ok.

 @@ -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?

Yes, this is one of the two bugs I've fixed since.

 +#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. :)

I find it tidier.

 +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()?

This will not happen, but note that one size is 64 bits and the other
can be 32 so I would need to use an intermediate variable.

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.

Sure, I will fix that.

christos



re: lwp resource limit

2012-06-04 Thread matthew green

 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?
 
 I just followed the pattern with maxproc. I will bump the limit, but I
 think that putting in the header is a mistake because things might use
 the constant thinking that it always represents reality.

make it a #define in kern_lwp.c itself, that can be pre-defined.

 For allowing process creation when maxlwp limit is exhausted, I would
 say this problem is better solved with maxprocperuid you mentioned.
 
 Yes, perhaps. I think that the process/lwp limits need to be re-thought.

i would say that the best way to handle this would be to not count
the first lwp in any process as part of the lwp rlimit.


.mrg.


re: lwp resource limit

2012-06-04 Thread Christos Zoulas
On Jun 5,  6:14am, m...@eterna.com.au (matthew green) wrote:
-- Subject: re: lwp resource limit

| 
|  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?
|  
|  I just followed the pattern with maxproc. I will bump the limit, but I
|  think that putting in the header is a mistake because things might use
|  the constant thinking that it always represents reality.
| 
| make it a #define in kern_lwp.c itself, that can be pre-defined.

will do.

|  For allowing process creation when maxlwp limit is exhausted, I would
|  say this problem is better solved with maxprocperuid you mentioned.
|  
|  Yes, perhaps. I think that the process/lwp limits need to be re-thought.
| 
| i would say that the best way to handle this would be to not count
| the first lwp in any process as part of the lwp rlimit.

That is a good idea! The only problem with it is that ps -sx and the sysctl
limit will not match (the limit will be lower than the sysctl number by the
number of processes). It does have the nice property though that the process
gets created anyway, as it is now (counting the limit).

It is a very simple change, and if people prefer it, I will do it.

christos


Re: lwp resource limit

2012-06-04 Thread Thor Lancelot Simon
On Mon, Jun 04, 2012 at 06:13:09PM -0400, Christos Zoulas wrote:
 
 That is a good idea! The only problem with it is that ps -sx and the sysctl
 limit will not match (the limit will be lower than the sysctl number by the
 number of processes). It does have the nice property though that the process
 gets created anyway, as it is now (counting the limit).
 
 It is a very simple change, and if people prefer it, I will do it.

I think it's truly elegant.  Do it!

Thor


Re: lwp resource limit

2012-06-04 Thread Christos Zoulas
In article 20120605013242.ga7...@panix.com,
Thor Lancelot Simon  t...@panix.com wrote:
On Mon, Jun 04, 2012 at 06:13:09PM -0400, Christos Zoulas wrote:
 
 That is a good idea! The only problem with it is that ps -sx and the sysctl
 limit will not match (the limit will be lower than the sysctl number by the
 number of processes). It does have the nice property though that the process
 gets created anyway, as it is now (counting the limit).
 
 It is a very simple change, and if people prefer it, I will do it.

I think it's truly elegant.  Do it!

I'll need to burn a bit in the lwp flags to indicate that exit should not
decrease the count, or hardcode not to do it for lid == 1. Which one do
you prefer?

christos



Re: lwp resource limit

2012-06-03 Thread Mindaugas Rasiukevicius
chris...@zoulas.com (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 -  1.442
 +++ kern/init_main.c  23 May 2012 23:19:31 -
 @@ -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 -  1.199
 +++ sys/sysctl.h  23 May 2012 23:19:36 -
 @@ -266,7 +266,8 @@ struct ctlname {
  #define  KERN_SYSVIPC82  /* node: SysV IPC
  #parameters */ defineKERN_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 */ +#defineKERN_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


Re: lwp resource limit

2012-06-03 Thread David Young
On Wed, May 23, 2012 at 07:37:19PM -0400, Christos Zoulas wrote:
 Hello,
 
 This is a new resource limit to prevent users from exhausting kernel
 resources that lwps use.
 
 - The limit is per uid
 - The default is 1024 per user unless the architecture overrides it
 - The kernel is never prohibited from creating threads
 - Exceeding the thread limit does not prevent process creation, but
   it will prevent processes from creating additional threads. So the
   effective thread limit is nlwp + nproc
 - The name NTHR was chosen to follow prior art
 - There could be atomicity issues for setuid and lwp exits
 - This diff also adds a sysctl kern.uidinfo.* to show the user the uid
   limits
 
 comments?
 
 christos
 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 -  1.442
 +++ kern/init_main.c  23 May 2012 23:19:31 -
 @@ -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;
  
  cprng_strong_t   *kern_cprng;
  
 @@ -291,6 +292,12 @@ main(void)
  #endif
   l-l_pflag |= LP_RUNNING;
  
 +#ifdef __HAVE_CPU_MAXLWP
 + maxlwp = cpu_maxlwp();
 +#else
 + maxlwp = 1024;
 +#endif
 +

Configuring the kernel with the preprocessor is just so ... wordy. :-)
Maybe use the linker instead?  E.g., provide a weak alias to a default
implementation of cpu_maxlwp() and a strong alias to the MD override on
architectures that have one.

Dave

-- 
David Young
dyo...@pobox.comUrbana, IL(217) 721-9981


Re: lwp resource limit

2012-05-24 Thread YAMAMOTO Takashi
hi,

 Hello,
 
 This is a new resource limit to prevent users from exhausting kernel
 resources that lwps use.
 
 - The limit is per uid
 - The default is 1024 per user unless the architecture overrides it
 - The kernel is never prohibited from creating threads
 - Exceeding the thread limit does not prevent process creation, but
   it will prevent processes from creating additional threads. So the
   effective thread limit is nlwp + nproc
 - The name NTHR was chosen to follow prior art

can you provide a pointer to the prior art?
is it API compatible?

YAMAMOTO Takashi

 - There could be atomicity issues for setuid and lwp exits
 - This diff also adds a sysctl kern.uidinfo.* to show the user the uid
   limits
 
 comments?


Re: lwp resource limit

2012-05-24 Thread Joerg Sonnenberger
On Wed, May 23, 2012 at 07:37:19PM -0400, Christos Zoulas wrote:
 This is a new resource limit to prevent users from exhausting kernel
 resources that lwps use.

Any reason for not using kern.maxproc as (hard) default limit?
It doesn't make sense to allow less threads than processes and I'm not
sure it is necessary to allow more threads, except that ulimit -p is
kind of small.

Joerg


Re: lwp resource limit

2012-05-24 Thread Christos Zoulas
On May 24,  6:55am, y...@mwd.biglobe.ne.jp (YAMAMOTO Takashi) wrote:
-- Subject: Re: lwp resource limit

| hi,
| 
|  Hello,
|  
|  This is a new resource limit to prevent users from exhausting kernel
|  resources that lwps use.
|  
|  - The limit is per uid
|  - The default is 1024 per user unless the architecture overrides it
|  - The kernel is never prohibited from creating threads
|  - Exceeding the thread limit does not prevent process creation, but
|it will prevent processes from creating additional threads. So the
|effective thread limit is nlwp + nproc
|  - The name NTHR was chosen to follow prior art
| 
| can you provide a pointer to the prior art?
| is it API compatible?

https://bdsc.webapps.blackberry.com/native/reference/com.qnx.doc.neutrino.lib_ref/topic/g/getrlimit.html

christos


Re: lwp resource limit

2012-05-24 Thread Christos Zoulas
In article 20120524090652.gc8...@britannica.bec.de,
Joerg Sonnenberger  jo...@britannica.bec.de wrote:
On Wed, May 23, 2012 at 07:37:19PM -0400, Christos Zoulas wrote:
 This is a new resource limit to prevent users from exhausting kernel
 resources that lwps use.

Any reason for not using kern.maxproc as (hard) default limit?
It doesn't make sense to allow less threads than processes and I'm not
sure it is necessary to allow more threads, except that ulimit -p is
kind of small.

Aside that having a separate limit is more flexible, and that current
maxproc is too small no. The current usage is that most processes have
just one thread, so what you are saying is true. It is simple to do either,
what do others think?

As a tangent, I also like what macosx did splitting maxproc and maxprocperuid.

christos



Re: lwp resource limit

2012-05-24 Thread David Laight
On Thu, May 24, 2012 at 02:14:27PM +, Christos Zoulas wrote:
 
 As a tangent, I also like what macosx did splitting maxproc and maxprocperuid.

I'm not sure that the kern.maxproc shouldn't just be deleted.
Your maxprocperuid is just the default value for 'ulimit -h -p'
(or perhaps the soft limit...)

David

-- 
David Laight: da...@l8s.co.uk


lwp resource limit

2012-05-23 Thread Christos Zoulas
Hello,

This is a new resource limit to prevent users from exhausting kernel
resources that lwps use.

- The limit is per uid
- The default is 1024 per user unless the architecture overrides it
- The kernel is never prohibited from creating threads
- Exceeding the thread limit does not prevent process creation, but
  it will prevent processes from creating additional threads. So the
  effective thread limit is nlwp + nproc
- The name NTHR was chosen to follow prior art
- There could be atomicity issues for setuid and lwp exits
- This diff also adds a sysctl kern.uidinfo.* to show the user the uid
  limits

comments?

christos
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.c19 Feb 2012 21:06:47 -  1.442
+++ kern/init_main.c23 May 2012 23:19:31 -
@@ -256,6 +256,7 @@ int cold = 1;   /* still working on star
 struct timespec boottime;  /* time at system startup - will only 
follow settime deltas */
 
 intstart_init_exec;/* semaphore for start_init() */
+intmaxlwp;
 
 cprng_strong_t *kern_cprng;
 
@@ -291,6 +292,12 @@ main(void)
 #endif
l-l_pflag |= LP_RUNNING;
 
+#ifdef __HAVE_CPU_MAXLWP
+   maxlwp = cpu_maxlwp();
+#else
+   maxlwp = 1024;
+#endif
+
/*
 * Attempt to find console and initialize
 * in case of early panic or other messages.
Index: kern/init_sysctl.c
===
RCS file: /cvsroot/src/sys/kern/init_sysctl.c,v
retrieving revision 1.189
diff -u -p -u -r1.189 init_sysctl.c
--- kern/init_sysctl.c  7 Apr 2012 05:38:49 -   1.189
+++ kern/init_sysctl.c  23 May 2012 23:19:31 -
@@ -147,6 +147,7 @@ static int sysctl_kern_trigger_panic(SYS
 static int sysctl_kern_maxvnodes(SYSCTLFN_PROTO);
 static int sysctl_kern_rtc_offset(SYSCTLFN_PROTO);
 static int sysctl_kern_maxproc(SYSCTLFN_PROTO);
+static int sysctl_kern_maxlwp(SYSCTLFN_PROTO);
 static int sysctl_kern_hostid(SYSCTLFN_PROTO);
 static int sysctl_setlen(SYSCTLFN_PROTO);
 static int sysctl_kern_clockrate(SYSCTLFN_PROTO);
@@ -234,6 +235,12 @@ SYSCTL_SETUP(sysctl_kern_setup, sysctl 
   CTL_KERN, KERN_MAXPROC, CTL_EOL);
sysctl_createv(clog, 0, NULL, NULL,
   CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
+  CTLTYPE_INT, maxlwp,
+  SYSCTL_DESCR(Maximum number of simultaneous threads),
+  sysctl_kern_maxlwp, 0, NULL, 0,
+  CTL_KERN, KERN_MAXLWP, CTL_EOL);
+   sysctl_createv(clog, 0, NULL, NULL,
+  CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
   CTLTYPE_INT, maxfiles,
   SYSCTL_DESCR(Maximum number of open files),
   NULL, 0, maxfiles, 0,
@@ -1050,6 +1057,33 @@ sysctl_kern_maxproc(SYSCTLFN_ARGS)
 }
 
 /*
+ * sysctl helper routine for kern.maxlwp. Ensures that the new
+ * values are not too low or too high.
+ */
+static int
+sysctl_kern_maxlwp(SYSCTLFN_ARGS)
+{
+   int error, nmaxlwp;
+   struct sysctlnode node;
+
+   nmaxlwp = maxlwp;
+   node = *rnode;
+   node.sysctl_data = nmaxlwp;
+   error = sysctl_lookup(SYSCTLFN_CALL(node));
+   if (error || newp == NULL)
+   return error;
+
+   if (nmaxlwp  0 || nmaxlwp = 65536)
+   return EINVAL;
+#ifdef __HAVE_CPU_MAXLWP
+   if (nmaxlwp  cpu_maxlwp())
+   return EINVAL;
+#endif
+   maxlwp = nmaxlwp;
+
+   return 0;
+}
+/*
  * sysctl helper function for kern.hostid. The hostid is a long, but
  * we export it as an int, so we need to give it a little help.
  */
Index: kern/kern_exec.c
===
RCS file: /cvsroot/src/sys/kern/kern_exec.c,v
retrieving revision 1.352
diff -u -p -u -r1.352 kern_exec.c
--- kern/kern_exec.c2 May 2012 23:33:11 -   1.352
+++ kern/kern_exec.c23 May 2012 23:19:32 -
@@ -2295,7 +2295,7 @@ do_posix_spawn(struct lwp *l1, pid_t *pi
 
/* create LWP */
lwp_create(l1, p2, uaddr, 0, NULL, 0, spawn_return, spawn_data,
-   l2, l1-l_class);
+   l2, l1-l_class, 0);
l2-l_ctxlink = NULL;   /* reset ucontext link */
 
/*
Index: kern/kern_fork.c
===
RCS file: /cvsroot/src/sys/kern/kern_fork.c,v
retrieving revision 1.189
diff -u -p -u -r1.189 kern_fork.c
--- kern/kern_fork.c13 Mar 2012 18:40:52 -  1.189
+++ kern/kern_fork.c23 May 2012 23:19:32 -
@@ -426,7 +426,7 @@ fork1(struct lwp *l1, int flags, int exi
 */
lwp_create(l1, p2, uaddr, (flags  FORK_PPWAIT) ? LWP_VFORK : 0,
stack, stacksize, (func != NULL) ? func : child_return, arg, l2,
-   l1-l_class);
+