Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 6 Apr 2011 18:11:25 +0000 (UTC)
From:      Edward Tomasz Napierala <trasz@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r220398 - head/sys/kern
Message-ID:  <201104061811.p36IBPrg009926@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: trasz
Date: Wed Apr  6 18:11:24 2011
New Revision: 220398
URL: http://svn.freebsd.org/changeset/base/220398

Log:
  Add accounting for SysV-related resources.
  
  Sponsored by:	The FreeBSD Foundation
  Reviewed by:	kib (earlier version)

Modified:
  head/sys/kern/sysv_msg.c
  head/sys/kern/sysv_sem.c
  head/sys/kern/sysv_shm.c

Modified: head/sys/kern/sysv_msg.c
==============================================================================
--- head/sys/kern/sysv_msg.c	Wed Apr  6 18:03:49 2011	(r220397)
+++ head/sys/kern/sysv_msg.c	Wed Apr  6 18:11:24 2011	(r220398)
@@ -63,6 +63,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/mutex.h>
 #include <sys/module.h>
 #include <sys/msg.h>
+#include <sys/racct.h>
 #include <sys/syscall.h>
 #include <sys/syscallsubr.h>
 #include <sys/sysent.h>
@@ -466,6 +467,9 @@ kern_msgctl(td, msqid, cmd, msqbuf)
 		}
 #endif
 
+		racct_sub_cred(msqkptr->cred, RACCT_NMSGQ, 1);
+		racct_sub_cred(msqkptr->cred, RACCT_MSGQQUEUED, msqkptr->u.msg_qnum);
+		racct_sub_cred(msqkptr->cred, RACCT_MSGQSIZE, msqkptr->u.msg_cbytes);
 		crfree(msqkptr->cred);
 		msqkptr->cred = NULL;
 
@@ -616,6 +620,13 @@ msgget(td, uap)
 			error = ENOSPC;
 			goto done2;
 		}
+		PROC_LOCK(td->td_proc);
+		error = racct_add(td->td_proc, RACCT_NMSGQ, 1);
+		PROC_UNLOCK(td->td_proc);
+		if (error != 0) {
+			error = ENOSPC;
+			goto done2;
+		}
 		DPRINTF(("msqid %d is available\n", msqid));
 		msqkptr->u.msg_perm.key = key;
 		msqkptr->u.msg_perm.cuid = cred->cr_uid;
@@ -675,6 +686,7 @@ kern_msgsnd(td, msqid, msgp, msgsz, msgf
 	register struct msqid_kernel *msqkptr;
 	register struct msg *msghdr;
 	short next;
+	size_t saved_msgsz;
 
 	if (!prison_allow(td->td_ucred, PR_ALLOW_SYSVIPC))
 		return (ENOSYS);
@@ -712,6 +724,21 @@ kern_msgsnd(td, msqid, msgp, msgsz, msgf
 		goto done2;
 #endif
 
+	PROC_LOCK(td->td_proc);
+	if (racct_add(td->td_proc, RACCT_MSGQQUEUED, 1)) {
+		PROC_UNLOCK(td->td_proc);
+		error = EAGAIN;
+		goto done2;
+	}
+	saved_msgsz = msgsz;
+	if (racct_add(td->td_proc, RACCT_MSGQSIZE, msgsz)) {
+		racct_sub(td->td_proc, RACCT_MSGQQUEUED, 1);
+		PROC_UNLOCK(td->td_proc);
+		error = EAGAIN;
+		goto done2;
+	}
+	PROC_UNLOCK(td->td_proc);
+
 	segs_needed = (msgsz + msginfo.msgssz - 1) / msginfo.msgssz;
 	DPRINTF(("msgsz=%zu, msgssz=%d, segs_needed=%d\n", msgsz,
 	    msginfo.msgssz, segs_needed));
@@ -726,7 +753,7 @@ kern_msgsnd(td, msqid, msgp, msgsz, msgf
 		if (msgsz > msqkptr->u.msg_qbytes) {
 			DPRINTF(("msgsz > msqkptr->u.msg_qbytes\n"));
 			error = EINVAL;
-			goto done2;
+			goto done3;
 		}
 
 		if (msqkptr->u.msg_perm.mode & MSG_LOCKED) {
@@ -753,7 +780,7 @@ kern_msgsnd(td, msqid, msgp, msgsz, msgf
 				DPRINTF(("need more resources but caller "
 				    "doesn't want to wait\n"));
 				error = EAGAIN;
-				goto done2;
+				goto done3;
 			}
 
 			if ((msqkptr->u.msg_perm.mode & MSG_LOCKED) != 0) {
@@ -779,7 +806,7 @@ kern_msgsnd(td, msqid, msgp, msgsz, msgf
 			if (error != 0) {
 				DPRINTF(("msgsnd:  interrupted system call\n"));
 				error = EINTR;
-				goto done2;
+				goto done3;
 			}
 
 			/*
@@ -789,7 +816,7 @@ kern_msgsnd(td, msqid, msgp, msgsz, msgf
 			if (msqkptr->u.msg_qbytes == 0) {
 				DPRINTF(("msqid deleted\n"));
 				error = EIDRM;
-				goto done2;
+				goto done3;
 			}
 
 		} else {
@@ -871,7 +898,7 @@ kern_msgsnd(td, msqid, msgp, msgsz, msgf
 		wakeup(msqkptr);
 		DPRINTF(("mtype (%ld) < 1\n", msghdr->msg_type));
 		error = EINVAL;
-		goto done2;
+		goto done3;
 	}
 
 	/*
@@ -898,7 +925,7 @@ kern_msgsnd(td, msqid, msgp, msgsz, msgf
 			msg_freehdr(msghdr);
 			msqkptr->u.msg_perm.mode &= ~MSG_LOCKED;
 			wakeup(msqkptr);
-			goto done2;
+			goto done3;
 		}
 		mtx_lock(&msq_mtx);
 		msgsz -= tlen;
@@ -922,7 +949,7 @@ kern_msgsnd(td, msqid, msgp, msgsz, msgf
 		msg_freehdr(msghdr);
 		wakeup(msqkptr);
 		error = EIDRM;
-		goto done2;
+		goto done3;
 	}
 
 #ifdef MAC
@@ -941,7 +968,7 @@ kern_msgsnd(td, msqid, msgp, msgsz, msgf
 	if (error != 0) {
 		msg_freehdr(msghdr);
 		wakeup(msqkptr);
-		goto done2;
+		goto done3;
 	}
 #endif
 
@@ -964,6 +991,13 @@ kern_msgsnd(td, msqid, msgp, msgsz, msgf
 
 	wakeup(msqkptr);
 	td->td_retval[0] = 0;
+done3:
+	if (error != 0) {
+		PROC_LOCK(td->td_proc);
+		racct_sub(td->td_proc, RACCT_MSGQQUEUED, 1);
+		racct_sub(td->td_proc, RACCT_MSGQSIZE, saved_msgsz);
+		PROC_UNLOCK(td->td_proc);
+	}
 done2:
 	mtx_unlock(&msq_mtx);
 	return (error);
@@ -1197,6 +1231,9 @@ kern_msgrcv(td, msqid, msgp, msgsz, msgt
 	msqkptr->u.msg_lrpid = td->td_proc->p_pid;
 	msqkptr->u.msg_rtime = time_second;
 
+	racct_sub_cred(msqkptr->cred, RACCT_MSGQQUEUED, 1);
+	racct_sub_cred(msqkptr->cred, RACCT_MSGQSIZE, msghdr->msg_ts);
+
 	/*
 	 * Make msgsz the actual amount that we'll be returning.
 	 * Note that this effectively truncates the message if it is too long

Modified: head/sys/kern/sysv_sem.c
==============================================================================
--- head/sys/kern/sysv_sem.c	Wed Apr  6 18:03:49 2011	(r220397)
+++ head/sys/kern/sysv_sem.c	Wed Apr  6 18:11:24 2011	(r220398)
@@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/lock.h>
 #include <sys/module.h>
 #include <sys/mutex.h>
+#include <sys/racct.h>
 #include <sys/sem.h>
 #include <sys/syscall.h>
 #include <sys/syscallsubr.h>
@@ -656,6 +657,7 @@ kern_semctl(struct thread *td, int semid
 		semakptr->u.sem_perm.cuid = cred->cr_uid;
 		semakptr->u.sem_perm.uid = cred->cr_uid;
 		semakptr->u.sem_perm.mode = 0;
+		racct_sub_cred(semakptr->cred, RACCT_NSEM, semakptr->u.sem_nsems);
 		crfree(semakptr->cred);
 		semakptr->cred = NULL;
 		SEMUNDO_LOCK();
@@ -929,6 +931,13 @@ semget(struct thread *td, struct semget_
 			error = ENOSPC;
 			goto done2;
 		}
+		PROC_LOCK(td->td_proc);
+		error = racct_add(td->td_proc, RACCT_NSEM, nsems);
+		PROC_UNLOCK(td->td_proc);
+		if (error != 0) {
+			error = ENOSPC;
+			goto done2;
+		}
 		DPRINTF(("semid %d is available\n", semid));
 		mtx_lock(&sema_mtx[semid]);
 		KASSERT((sema[semid].u.sem_perm.mode & SEM_ALLOC) == 0,
@@ -1010,12 +1019,19 @@ semop(struct thread *td, struct semop_ar
 	/* Allocate memory for sem_ops */
 	if (nsops <= SMALL_SOPS)
 		sops = small_sops;
-	else if (nsops <= seminfo.semopm)
-		sops = malloc(nsops * sizeof(*sops), M_TEMP, M_WAITOK);
-	else {
+	else if (nsops > seminfo.semopm) {
 		DPRINTF(("too many sops (max=%d, nsops=%d)\n", seminfo.semopm,
 		    nsops));
 		return (E2BIG);
+	} else {
+		PROC_LOCK(td->td_proc);
+		if (nsops > racct_get_available(td->td_proc, RACCT_NSEMOP)) {
+			PROC_UNLOCK(td->td_proc);
+			return (E2BIG);
+		}
+		PROC_UNLOCK(td->td_proc);
+
+		sops = malloc(nsops * sizeof(*sops), M_TEMP, M_WAITOK);
 	}
 	if ((error = copyin(uap->sops, sops, nsops * sizeof(sops[0]))) != 0) {
 		DPRINTF(("error = %d from copyin(%p, %p, %d)\n", error,

Modified: head/sys/kern/sysv_shm.c
==============================================================================
--- head/sys/kern/sysv_shm.c	Wed Apr  6 18:03:49 2011	(r220397)
+++ head/sys/kern/sysv_shm.c	Wed Apr  6 18:11:24 2011	(r220398)
@@ -77,6 +77,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/mman.h>
 #include <sys/module.h>
 #include <sys/mutex.h>
+#include <sys/racct.h>
 #include <sys/resourcevar.h>
 #include <sys/stat.h>
 #include <sys/syscall.h>
@@ -246,6 +247,8 @@ shm_deallocate_segment(shmseg)
 #ifdef MAC
 	mac_sysvshm_cleanup(shmseg);
 #endif
+	racct_sub_cred(shmseg->cred, RACCT_NSHM, 1);
+	racct_sub_cred(shmseg->cred, RACCT_SHMSIZE, size);
 	crfree(shmseg->cred);
 	shmseg->cred = NULL;
 }
@@ -669,6 +672,17 @@ shmget_allocate_segment(td, uap, mode)
 		shm_last_free = -1;
 	}
 	shmseg = &shmsegs[segnum];
+	PROC_LOCK(td->td_proc);
+	if (racct_add(td->td_proc, RACCT_NSHM, 1)) {
+		PROC_UNLOCK(td->td_proc);
+		return (ENOSPC);
+	}
+	if (racct_add(td->td_proc, RACCT_SHMSIZE, size)) {
+		racct_sub(td->td_proc, RACCT_NSHM, 1);
+		PROC_UNLOCK(td->td_proc);
+		return (ENOMEM);
+	}
+	PROC_UNLOCK(td->td_proc);
 	/*
 	 * In case we sleep in malloc(), mark the segment present but deleted
 	 * so that noone else tries to create the same key.
@@ -684,8 +698,13 @@ shmget_allocate_segment(td, uap, mode)
 	 */
 	shm_object = vm_pager_allocate(shm_use_phys ? OBJT_PHYS : OBJT_SWAP,
 	    0, size, VM_PROT_DEFAULT, 0, cred);
-	if (shm_object == NULL)
+	if (shm_object == NULL) {
+		PROC_LOCK(td->td_proc);
+		racct_sub(td->td_proc, RACCT_NSHM, 1);
+		racct_sub(td->td_proc, RACCT_SHMSIZE, size);
+		PROC_UNLOCK(td->td_proc);
 		return (ENOMEM);
+	}
 	VM_OBJECT_LOCK(shm_object);
 	vm_object_clear_flag(shm_object, OBJ_ONEMAPPING);
 	vm_object_set_flag(shm_object, OBJ_NOSPLIT);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201104061811.p36IBPrg009926>