From owner-svn-src-all@FreeBSD.ORG Wed Apr 6 18:11:25 2011 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id B9821106566C; Wed, 6 Apr 2011 18:11:25 +0000 (UTC) (envelope-from trasz@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id A79C08FC14; Wed, 6 Apr 2011 18:11:25 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id p36IBPCO009930; Wed, 6 Apr 2011 18:11:25 GMT (envelope-from trasz@svn.freebsd.org) Received: (from trasz@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id p36IBPrg009926; Wed, 6 Apr 2011 18:11:25 GMT (envelope-from trasz@svn.freebsd.org) Message-Id: <201104061811.p36IBPrg009926@svn.freebsd.org> From: Edward Tomasz Napierala Date: Wed, 6 Apr 2011 18:11:25 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r220398 - head/sys/kern X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 06 Apr 2011 18:11:25 -0000 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 #include #include +#include #include #include #include @@ -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 #include #include +#include #include #include #include @@ -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 #include #include +#include #include #include #include @@ -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);