[Midnightbsd-cvs] src [7782] trunk: Add a resource limit for the total number of kqueues

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Mon Sep 5 12:20:48 EDT 2016


Revision: 7782
          http://svnweb.midnightbsd.org/src/?rev=7782
Author:   laffer1
Date:     2016-09-05 12:20:48 -0400 (Mon, 05 Sep 2016)
Log Message:
-----------
Add a resource limit for the total number of kqueues
available to the user. Kqueue now saves the ucred of the
allocating thread, to correctly decrement the counter on close.
Based on FreeBSD SVN 256849

Modified Paths:
--------------
    trunk/UPDATING
    trunk/sys/kern/kern_event.c
    trunk/sys/kern/kern_resource.c
    trunk/sys/sys/eventvar.h
    trunk/sys/sys/resource.h
    trunk/sys/sys/resourcevar.h

Modified: trunk/UPDATING
===================================================================
--- trunk/UPDATING	2016-09-05 16:12:10 UTC (rev 7781)
+++ trunk/UPDATING	2016-09-05 16:20:48 UTC (rev 7782)
@@ -1,5 +1,11 @@
 Updating Information for MidnightBSD users.
 
+20160905:
+	Add a resource limit for the total number of kqueues
+	available to the user. Kqueue now saves the ucred of the
+	allocating thread, to correctly decrement the counter on close.
+	Based on FreeBSD SVN 256849
+
 20160814:
 	switched default desktop port to midnightbsd-desktop. This gives us flexibility to change it
 	in the release after the fact.

Modified: trunk/sys/kern/kern_event.c
===================================================================
--- trunk/sys/kern/kern_event.c	2016-09-05 16:12:10 UTC (rev 7781)
+++ trunk/sys/kern/kern_event.c	2016-09-05 16:20:48 UTC (rev 7782)
@@ -51,6 +51,7 @@
 #include <sys/eventvar.h>
 #include <sys/poll.h>
 #include <sys/protosw.h>
+#include <sys/resourcevar.h>
 #include <sys/sigio.h>
 #include <sys/signalvar.h>
 #include <sys/socket.h>
@@ -684,9 +685,23 @@
 	struct filedesc *fdp;
 	struct kqueue *kq;
 	struct file *fp;
+	struct proc *p;
+	struct ucred *cred;
 	int fd, error;
 
-	fdp = td->td_proc->p_fd;
+	p = td->td_proc;
+	cred = td->td_ucred;
+	crhold(cred);
+	PROC_LOCK(p);
+	if (!chgkqcnt(cred->cr_ruidinfo, 1, lim_cur(td->td_proc,
+	    RLIMIT_KQUEUES))) {
+		PROC_UNLOCK(p);
+		crfree(cred);
+		return (EMFILE);
+	}
+	PROC_UNLOCK(p);
+
+	fdp = p->p_fd;
 	error = falloc(td, &fp, &fd, 0);
 	if (error)
 		goto done2;
@@ -696,6 +711,7 @@
 	mtx_init(&kq->kq_lock, "kqueue", NULL, MTX_DEF|MTX_DUPOK);
 	TAILQ_INIT(&kq->kq_head);
 	kq->kq_fdp = fdp;
+	kq->kq_cred = cred;
 	knlist_init_mtx(&kq->kq_sel.si_note, &kq->kq_lock);
 	TASK_INIT(&kq->kq_task, 0, kqueue_task, kq);
 
@@ -708,6 +724,10 @@
 
 	td->td_retval[0] = fd;
 done2:
+	if (error != 0) {
+		chgkqcnt(cred->cr_ruidinfo, -1, 0);
+		crfree(cred);
+	}
 	return (error);
 }
 
@@ -1715,6 +1735,8 @@
 		free(kq->kq_knlist, M_KQUEUE);
 
 	funsetown(&kq->kq_sigio);
+	chgkqcnt(kq->kq_cred->cr_ruidinfo, -1, 0);
+	crfree(kq->kq_cred);
 	free(kq, M_KQUEUE);
 	fp->f_data = NULL;
 

Modified: trunk/sys/kern/kern_resource.c
===================================================================
--- trunk/sys/kern/kern_resource.c	2016-09-05 16:12:10 UTC (rev 7781)
+++ trunk/sys/kern/kern_resource.c	2016-09-05 16:20:48 UTC (rev 7782)
@@ -1425,3 +1425,21 @@
 	}
 	return (1);
 }
+
+int
+chgkqcnt(struct uidinfo *uip, int diff, rlim_t max)
+{
+
+	if (diff > 0 && max != 0) {
+		if (atomic_fetchadd_long(&uip->ui_kqcnt, (long)diff) +
+		    diff > max) {
+			atomic_subtract_long(&uip->ui_kqcnt, (long)diff);
+			return (0);
+		}
+	} else {
+		atomic_add_long(&uip->ui_kqcnt, (long)diff);
+		if (uip->ui_kqcnt < 0)
+			printf("negative kqcnt for uid = %d\n", uip->ui_uid);
+	}
+	return (1);
+}

Modified: trunk/sys/sys/eventvar.h
===================================================================
--- trunk/sys/sys/eventvar.h	2016-09-05 16:12:10 UTC (rev 7781)
+++ trunk/sys/sys/eventvar.h	2016-09-05 16:20:48 UTC (rev 7782)
@@ -60,6 +60,7 @@
 	u_long		kq_knhashmask;		/* size of knhash */
 	struct		klist *kq_knhash;	/* hash table for knotes */
 	struct		task kq_task;
+	struct		ucred *kq_cred;
 };
 
 #endif /* !_SYS_EVENTVAR_H_ */

Modified: trunk/sys/sys/resource.h
===================================================================
--- trunk/sys/sys/resource.h	2016-09-05 16:12:10 UTC (rev 7781)
+++ trunk/sys/sys/resource.h	2016-09-05 16:20:48 UTC (rev 7782)
@@ -103,8 +103,9 @@
 #define	RLIMIT_AS	RLIMIT_VMEM	/* standard name for RLIMIT_VMEM */
 #define	RLIMIT_NPTS	11		/* pseudo-terminals */
 #define	RLIMIT_SWAP	12		/* swap used */
+#define	RLIMIT_KQUEUES	13		/* kqueues allocated */
 
-#define	RLIM_NLIMITS	13		/* number of resource limits */
+#define	RLIM_NLIMITS	14		/* number of resource limits */
 
 #define	RLIM_INFINITY	((rlim_t)(((uint64_t)1 << 63) - 1))
 /* XXX Missing: RLIM_SAVED_MAX, RLIM_SAVED_CUR */
@@ -129,6 +130,7 @@
 	"vmem",
 	"npts",
 	"swap",
+	"kqueues",
 };
 #endif
 

Modified: trunk/sys/sys/resourcevar.h
===================================================================
--- trunk/sys/sys/resourcevar.h	2016-09-05 16:12:10 UTC (rev 7781)
+++ trunk/sys/sys/resourcevar.h	2016-09-05 16:20:48 UTC (rev 7782)
@@ -99,6 +99,7 @@
 	long	ui_sbsize;		/* (b) socket buffer space consumed */
 	long	ui_proccnt;		/* (b) number of processes */
 	long	ui_ptscnt;		/* (b) number of pseudo-terminals */
+	long	ui_kqcnt;		/* (b) number of kqueues */
 	uid_t	ui_uid;			/* (a) uid */
 	u_int	ui_ref;			/* (b) reference count */
 	struct racct *ui_racct;		/* (a) resource accounting */
@@ -115,6 +116,7 @@
 void	 addupc_task(struct thread *td, uintfptr_t pc, u_int ticks);
 void	 calccru(struct proc *p, struct timeval *up, struct timeval *sp);
 void	 calcru(struct proc *p, struct timeval *up, struct timeval *sp);
+int	 chgkqcnt(struct uidinfo *uip, int diff, rlim_t max);
 int	 chgproccnt(struct uidinfo *uip, int diff, rlim_t maxval);
 int	 chgsbsize(struct uidinfo *uip, u_int *hiwat, u_int to,
 	    rlim_t maxval);



More information about the Midnightbsd-cvs mailing list