Page MenuHomeFreeBSD

D30775.id.diff
No OneTemporary

D30775.id.diff

diff --git a/sys/kern/kern_umtx.c b/sys/kern/kern_umtx.c
--- a/sys/kern/kern_umtx.c
+++ b/sys/kern/kern_umtx.c
@@ -4014,9 +4014,9 @@
reg = uma_zalloc(umtx_shm_reg_zone, M_WAITOK | M_ZERO);
reg->ushm_refcnt = 1;
bcopy(key, &reg->ushm_key, sizeof(*key));
- reg->ushm_obj = shm_alloc(td->td_ucred, O_RDWR, false);
+ reg->ushm_obj = shm_alloc(td, O_RDWR, false);
reg->ushm_cred = crhold(cred);
- error = shm_dotruncate(reg->ushm_obj, PAGE_SIZE);
+ error = shm_dotruncate(td, reg->ushm_obj, PAGE_SIZE);
if (error != 0) {
umtx_shm_free_reg(reg);
return (error);
diff --git a/sys/kern/uipc_shm.c b/sys/kern/uipc_shm.c
--- a/sys/kern/uipc_shm.c
+++ b/sys/kern/uipc_shm.c
@@ -73,6 +73,7 @@
#include <sys/mutex.h>
#include <sys/priv.h>
#include <sys/proc.h>
+#include <sys/racct.h>
#include <sys/refcount.h>
#include <sys/resourcevar.h>
#include <sys/rwlock.h>
@@ -125,10 +126,10 @@
static void shm_insert(char *path, Fnv32_t fnv, struct shmfd *shmfd);
static struct shmfd *shm_lookup(char *path, Fnv32_t fnv);
static int shm_remove(char *path, Fnv32_t fnv, struct ucred *ucred);
-static int shm_dotruncate_cookie(struct shmfd *shmfd, off_t length,
- void *rl_cookie);
-static int shm_dotruncate_locked(struct shmfd *shmfd, off_t length,
- void *rl_cookie);
+static int shm_dotruncate_cookie(struct thread *td, struct shmfd *shmfd,
+ off_t length, void *rl_cookie);
+static int shm_dotruncate_locked(struct thread *td, struct shmfd *shmfd,
+ off_t length, void *rl_cookie);
static int shm_copyin_path(struct thread *td, const char *userpath_in,
char **path_out);
@@ -450,7 +451,7 @@
error = 0;
if ((shmfd->shm_flags & SHM_GROW_ON_WRITE) != 0 &&
size > shmfd->shm_size) {
- error = shm_dotruncate_cookie(shmfd, size, rl_cookie);
+ error = shm_dotruncate_cookie(td, shmfd, size, rl_cookie);
}
if (error == 0)
error = uiomove_object(shmfd->shm_object,
@@ -476,7 +477,7 @@
if (error)
return (error);
#endif
- return (shm_dotruncate(shmfd, length));
+ return (shm_dotruncate(td, shmfd, length));
}
int
@@ -627,7 +628,7 @@
}
static int
-shm_dotruncate_locked(struct shmfd *shmfd, off_t length, void *rl_cookie)
+shm_dotruncate_locked(struct thread *td, struct shmfd *shmfd, off_t length, void *rl_cookie)
{
vm_object_t object;
vm_page_t m;
@@ -709,14 +710,39 @@
/* Free the swap accounted for shm */
swap_release_by_cred(delta, object->cred);
object->charge -= delta;
+#ifdef RACCT
+ if (racct_enable) {
+ racct_sub_cred(object->cred, RACCT_SHMSIZE,
+ shmfd->shm_size - length);
+ }
+#endif
} else {
if ((shmfd->shm_seals & F_SEAL_GROW) != 0)
return (EPERM);
+#ifdef RACCT
+ if (racct_enable) {
+ PROC_LOCK(td->td_proc);
+ if (racct_add_cred_checked(object->cred, RACCT_SHMSIZE,
+ length - shmfd->shm_size)) {
+ PROC_UNLOCK(td->td_proc);
+ return (ENOMEM);
+ }
+ PROC_UNLOCK(td->td_proc);
+ }
+#endif
+
/* Try to reserve additional swap space. */
delta = IDX_TO_OFF(nobjsize - object->size);
- if (!swap_reserve_by_cred(delta, object->cred))
+ if (!swap_reserve_by_cred(delta, object->cred)) {
+#ifdef RACCT
+ if (racct_enable) {
+ racct_sub_cred(object->cred, RACCT_SHMSIZE,
+ length - shmfd->shm_size);
+ }
+#endif
return (ENOMEM);
+ }
object->charge += delta;
}
shmfd->shm_size = length;
@@ -729,7 +755,7 @@
}
static int
-shm_dotruncate_largepage(struct shmfd *shmfd, off_t length, void *rl_cookie)
+shm_dotruncate_largepage(struct thread *td, struct shmfd *shmfd, off_t length, void *rl_cookie)
{
vm_object_t object;
vm_page_t m;
@@ -768,6 +794,17 @@
if ((shmfd->shm_seals & F_SEAL_GROW) != 0)
return (EPERM);
+#ifdef RACCT
+ if (racct_enable) {
+ PROC_LOCK(td->td_proc);
+ if (racct_add(td->td_proc, RACCT_SHMSIZE, length - shmfd->shm_size)) {
+ PROC_UNLOCK(td->td_proc);
+ return (ENOMEM);
+ }
+ PROC_UNLOCK(td->td_proc);
+ }
+#endif
+
aflags = VM_ALLOC_NORMAL | VM_ALLOC_ZERO;
if (shmfd->shm_lp_alloc_policy == SHM_LARGEPAGE_ALLOC_NOWAIT)
aflags |= VM_ALLOC_WAITFAIL;
@@ -790,6 +827,12 @@
(shmfd->shm_lp_alloc_policy ==
SHM_LARGEPAGE_ALLOC_DEFAULT &&
try >= largepage_reclaim_tries)) {
+#ifdef RACCT
+ if (racct_enable) {
+ racct_sub_cred(object->cred, RACCT_SHMSIZE,
+ length - shmfd->shm_size);
+ }
+#endif
VM_OBJECT_WLOCK(object);
return (ENOMEM);
}
@@ -799,6 +842,12 @@
vm_wait_intr(object);
if (error != 0) {
VM_OBJECT_WLOCK(object);
+#ifdef RACCT
+ if (racct_enable) {
+ racct_sub_cred(object->cred, RACCT_SHMSIZE,
+ length - shmfd->shm_size);
+ }
+#endif
return (error);
}
try++;
@@ -821,27 +870,27 @@
}
static int
-shm_dotruncate_cookie(struct shmfd *shmfd, off_t length, void *rl_cookie)
+shm_dotruncate_cookie(struct thread *td, struct shmfd *shmfd, off_t length, void *rl_cookie)
{
int error;
VM_OBJECT_WLOCK(shmfd->shm_object);
- error = shm_largepage(shmfd) ? shm_dotruncate_largepage(shmfd,
- length, rl_cookie) : shm_dotruncate_locked(shmfd, length,
+ error = shm_largepage(shmfd) ? shm_dotruncate_largepage(td, shmfd,
+ length, rl_cookie) : shm_dotruncate_locked(td, shmfd, length,
rl_cookie);
VM_OBJECT_WUNLOCK(shmfd->shm_object);
return (error);
}
int
-shm_dotruncate(struct shmfd *shmfd, off_t length)
+shm_dotruncate(struct thread *td, struct shmfd *shmfd, off_t length)
{
void *rl_cookie;
int error;
rl_cookie = rangelock_wlock(&shmfd->shm_rl, 0, OFF_MAX,
&shmfd->shm_mtx);
- error = shm_dotruncate_cookie(shmfd, length, rl_cookie);
+ error = shm_dotruncate_cookie(td, shmfd, length, rl_cookie);
rangelock_unlock(&shmfd->shm_rl, rl_cookie, &shmfd->shm_mtx);
return (error);
}
@@ -851,23 +900,34 @@
* routines.
*/
struct shmfd *
-shm_alloc(struct ucred *ucred, mode_t mode, bool largepage)
+shm_alloc(struct thread *td, mode_t mode, bool largepage)
{
struct shmfd *shmfd;
+#ifdef RACCT
+ if (racct_enable) {
+ PROC_LOCK(td->td_proc);
+ if (racct_add(td->td_proc, RACCT_NSHM, 1)) {
+ PROC_UNLOCK(td->td_proc);
+ return (NULL);
+ }
+ PROC_UNLOCK(td->td_proc);
+ }
+#endif
+
shmfd = malloc(sizeof(*shmfd), M_SHMFD, M_WAITOK | M_ZERO);
shmfd->shm_size = 0;
- shmfd->shm_uid = ucred->cr_uid;
- shmfd->shm_gid = ucred->cr_gid;
+ shmfd->shm_uid = td->td_ucred->cr_uid;
+ shmfd->shm_gid = td->td_ucred->cr_gid;
shmfd->shm_mode = mode;
if (largepage) {
shmfd->shm_object = phys_pager_allocate(NULL,
&shm_largepage_phys_ops, NULL, shmfd->shm_size,
- VM_PROT_DEFAULT, 0, ucred);
+ VM_PROT_DEFAULT, 0, td->td_ucred);
shmfd->shm_lp_alloc_policy = SHM_LARGEPAGE_ALLOC_DEFAULT;
} else {
shmfd->shm_object = vm_pager_allocate(OBJT_SWAP, NULL,
- shmfd->shm_size, VM_PROT_DEFAULT, 0, ucred);
+ shmfd->shm_size, VM_PROT_DEFAULT, 0, td->td_ucred);
}
KASSERT(shmfd->shm_object != NULL, ("shm_create: vm_pager_allocate"));
vfs_timestamp(&shmfd->shm_birthtime);
@@ -879,7 +939,7 @@
rangelock_init(&shmfd->shm_rl);
#ifdef MAC
mac_posixshm_init(shmfd);
- mac_posixshm_create(ucred, shmfd);
+ mac_posixshm_create(td->td_ucred, shmfd);
#endif
return (shmfd);
@@ -900,6 +960,13 @@
if (refcount_release(&shmfd->shm_refs)) {
#ifdef MAC
mac_posixshm_destroy(shmfd);
+#endif
+#ifdef RACCT
+ if (racct_enable) {
+ racct_sub_cred(shmfd->shm_object->cred, RACCT_NSHM, 1);
+ racct_sub_cred(shmfd->shm_object->cred, RACCT_SHMSIZE,
+ shmfd->shm_size);
+ }
#endif
rangelock_destroy(&shmfd->shm_rl);
mtx_destroy(&shmfd->shm_mtx);
@@ -1103,7 +1170,10 @@
fdrop(fp, td);
return (EINVAL);
}
- shmfd = shm_alloc(td->td_ucred, cmode, largepage);
+ shmfd = shm_alloc(td, cmode, largepage);
+ if (shmfd == NULL) {
+ return (ENOSPC);
+ }
shmfd->shm_seals = initial_seals;
shmfd->shm_flags = shmflags;
} else {
@@ -1126,8 +1196,11 @@
path);
if (error == 0) {
#endif
- shmfd = shm_alloc(td->td_ucred, cmode,
- largepage);
+ shmfd = shm_alloc(td, cmode, largepage);
+ if (shmfd == NULL) {
+ sx_xunlock(&shm_dict_lock);
+ return (ENOSPC);
+ }
shmfd->shm_seals = initial_seals;
shmfd->shm_flags = shmflags;
shm_insert(path, fnv, shmfd);
@@ -1199,8 +1272,8 @@
td->td_ucred, fp->f_cred, shmfd);
if (error == 0)
#endif
- error = shm_dotruncate_locked(shmfd, 0,
- rl_cookie);
+ error = shm_dotruncate_locked(td, shmfd,
+ 0, rl_cookie);
VM_OBJECT_WUNLOCK(shmfd->shm_object);
}
if (error == 0) {
@@ -1899,7 +1972,7 @@
rl_cookie = rangelock_wlock(&shmfd->shm_rl, offset, size,
&shmfd->shm_mtx);
if (size > shmfd->shm_size)
- error = shm_dotruncate_cookie(shmfd, size, rl_cookie);
+ error = shm_dotruncate_cookie(td, shmfd, size, rl_cookie);
rangelock_unlock(&shmfd->shm_rl, rl_cookie, &shmfd->shm_mtx);
/* Translate to posix_fallocate(2) return value as needed. */
if (error == ENOMEM)
diff --git a/sys/sys/mman.h b/sys/sys/mman.h
--- a/sys/sys/mman.h
+++ b/sys/sys/mman.h
@@ -304,10 +304,10 @@
int shm_unmap(struct file *fp, void *mem, size_t size);
int shm_access(struct shmfd *shmfd, struct ucred *ucred, int flags);
-struct shmfd *shm_alloc(struct ucred *ucred, mode_t mode, bool largepage);
+struct shmfd *shm_alloc(struct thread *td, mode_t mode, bool largepage);
struct shmfd *shm_hold(struct shmfd *shmfd);
void shm_drop(struct shmfd *shmfd);
-int shm_dotruncate(struct shmfd *shmfd, off_t length);
+int shm_dotruncate(struct thread *td, struct shmfd *shmfd, off_t length);
bool shm_largepage(struct shmfd *shmfd);
extern struct fileops shm_ops;
diff --git a/usr.bin/rctl/rctl.8 b/usr.bin/rctl/rctl.8
--- a/usr.bin/rctl/rctl.8
+++ b/usr.bin/rctl/rctl.8
@@ -190,8 +190,8 @@
.It Sy nmsgq Ta "number of SysV message queues"
.It Sy nsem Ta "number of SysV semaphores"
.It Sy nsemop Ta "number of SysV semaphores modified in a single semop(2) call"
-.It Sy nshm Ta "number of SysV shared memory segments"
-.It Sy shmsize Ta "SysV shared memory size, in bytes"
+.It Sy nshm Ta "number of SysV shared memory segments and POSIX shared memory objects"
+.It Sy shmsize Ta "SysV and POSIX shared memory size, in bytes"
.It Sy wallclock Ta "wallclock time, in seconds"
.It Sy pcpu Ta "%CPU, in percents of a single CPU core"
.It Sy readbps Ta "filesystem reads, in bytes per second"

File Metadata

Mime Type
text/plain
Expires
Sat, Feb 28, 11:31 PM (13 h, 1 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29086682
Default Alt Text
D30775.id.diff (10 KB)

Event Timeline