Page MenuHomeFreeBSD

D27100.id79211.diff
No OneTemporary

D27100.id79211.diff

Index: sys/kern/kern_thr.c
===================================================================
--- sys/kern/kern_thr.c
+++ sys/kern/kern_thr.c
@@ -67,7 +67,7 @@
static SYSCTL_NODE(_kern, OID_AUTO, threads, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
"thread allocation");
-static int max_threads_per_proc = 1500;
+int max_threads_per_proc = 1500;
SYSCTL_INT(_kern_threads, OID_AUTO, max_threads_per_proc, CTLFLAG_RW,
&max_threads_per_proc, 0, "Limit on threads per proc");
Index: sys/kern/kern_thread.c
===================================================================
--- sys/kern/kern_thread.c
+++ sys/kern/kern_thread.c
@@ -59,6 +59,7 @@
#ifdef HWPMC_HOOKS
#include <sys/pmckern.h>
#endif
+#include <sys/priv.h>
#include <security/audit/audit.h>
@@ -142,6 +143,12 @@
static int tid_head, tid_tail;
static MALLOC_DEFINE(M_TIDHASH, "tidhash", "thread hash");
+static int maxthread;
+SYSCTL_INT(_kern, OID_AUTO, maxthread, CTLFLAG_RDTUN,
+ &maxthread, 0, "Maximum number of threads");
+
+static int nthreads;
+
struct tidhashhead *tidhashtbl;
u_long tidhash;
struct rwlock tidhash_lock;
@@ -154,7 +161,24 @@
static lwpid_t
tid_alloc(void)
{
- lwpid_t tid;
+ static struct timeval lastfail;
+ static int curfail;
+ int nthreads_new;
+ lwpid_t tid;
+
+ nthreads_new = atomic_fetchadd_int(&nthreads, 1) + 1;
+ if (nthreads_new >= maxthread - 100) {
+ if (priv_check_cred(curthread->td_ucred, PRIV_MAXPROC) != 0 ||
+ nthreads_new >= maxthread) {
+ atomic_subtract_int(&nthreads, 1);
+ if (ppsratecheck(&lastfail, &curfail, 1)) {
+ printf("maxthread limit exceeded by uid %u "
+ "(pid %d); consider increasing kern.maxthread\n",
+ curthread->td_ucred->cr_ruid, curproc->p_pid);
+ }
+ return (-1);
+ }
+ }
tid = alloc_unr(tid_unrhdr);
if (tid != -1)
@@ -185,6 +209,7 @@
mtx_unlock(&tid_lock);
if (tmp_tid != -1)
free_unr(tid_unrhdr, tmp_tid);
+ atomic_subtract_int(&nthreads, 1);
}
/*
@@ -199,8 +224,6 @@
td->td_state = TDS_INACTIVE;
td->td_lastcpu = td->td_oncpu = NOCPU;
- td->td_tid = tid_alloc();
-
/*
* Note that td_critnest begins life as 1 because the thread is not
* running and is thereby implicitly waiting to be on the receiving
@@ -208,7 +231,6 @@
*/
td->td_critnest = 1;
td->td_lend_user_pri = PRI_MAX;
- EVENTHANDLER_DIRECT_INVOKE(thread_ctor, td);
#ifdef AUDIT
audit_thread_alloc(td);
#endif
@@ -253,9 +275,6 @@
osd_thread_exit(td);
td_softdep_cleanup(td);
MPASS(td->td_su == NULL);
-
- EVENTHANDLER_DIRECT_INVOKE(thread_dtor, td);
- tid_free(td->td_tid);
}
/*
@@ -325,6 +344,8 @@
thread_link(td, p);
}
+extern int max_threads_per_proc;
+
/*
* Initialize global thread allocation resources.
*/
@@ -333,6 +354,10 @@
{
uint32_t flags;
+ if (maxthread == 0) {
+ maxthread = MIN(maxproc * max_threads_per_proc, 1000000);
+ }
+
mtx_init(&tid_lock, "TID lock", NULL, MTX_DEF);
/*
@@ -415,16 +440,25 @@
thread_alloc(int pages)
{
struct thread *td;
+ lwpid_t tid;
thread_reap(); /* check if any zombies to get */
- td = (struct thread *)uma_zalloc(thread_zone, M_WAITOK);
+ tid = tid_alloc();
+ if (tid == -1) {
+ return (NULL);
+ }
+
+ td = uma_zalloc(thread_zone, M_WAITOK);
KASSERT(td->td_kstack == 0, ("thread_alloc got thread with kstack"));
if (!vm_thread_new(td, pages)) {
uma_zfree(thread_zone, td);
+ tid_free(tid);
return (NULL);
}
+ td->td_tid = tid;
cpu_thread_alloc(td);
+ EVENTHANDLER_DIRECT_INVOKE(thread_ctor, td);
return (td);
}
@@ -447,6 +481,7 @@
thread_free(struct thread *td)
{
+ EVENTHANDLER_DIRECT_INVOKE(thread_dtor, td);
lock_profile_thread_exit(td);
if (td->td_cpuset)
cpuset_rel(td->td_cpuset);
@@ -455,6 +490,8 @@
if (td->td_kstack != 0)
vm_thread_dispose(td);
callout_drain(&td->td_slpcallout);
+ tid_free(td->td_tid);
+ td->td_tid = -1;
uma_zfree(thread_zone, td);
}

File Metadata

Mime Type
text/plain
Expires
Thu, Oct 23, 1:15 AM (8 h, 22 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
24076839
Default Alt Text
D27100.id79211.diff (3 KB)

Event Timeline