Skip to content

Commit 3458bbd

Browse files
committed
kernel: add RLIMIT_PIPEBUF
Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D46619
1 parent 0ecbb28 commit 3458bbd

File tree

5 files changed

+28
-1
lines changed

5 files changed

+28
-1
lines changed

sys/kern/kern_resource.c

+7
Original file line numberDiff line numberDiff line change
@@ -1607,3 +1607,10 @@ chgumtxcnt(struct uidinfo *uip, int diff, rlim_t max)
16071607

16081608
return (chglimit(uip, &uip->ui_umtxcnt, diff, max, "umtxcnt"));
16091609
}
1610+
1611+
int
1612+
chgpipecnt(struct uidinfo *uip, int diff, rlim_t max)
1613+
{
1614+
1615+
return (chglimit(uip, &uip->ui_pipecnt, diff, max, "pipecnt"));
1616+
}

sys/kern/sys_pipe.c

+16
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,7 @@ pipe_paircreate(struct thread *td, struct pipepair **p_pp)
375375
#endif
376376
rpipe = &pp->pp_rpipe;
377377
wpipe = &pp->pp_wpipe;
378+
pp->pp_owner = crhold(td->td_ucred);
378379

379380
knlist_init_mtx(&rpipe->pipe_sel.si_note, PIPE_MTX(rpipe));
380381
knlist_init_mtx(&wpipe->pipe_sel.si_note, PIPE_MTX(wpipe));
@@ -408,6 +409,7 @@ pipe_paircreate(struct thread *td, struct pipepair **p_pp)
408409
fail:
409410
knlist_destroy(&rpipe->pipe_sel.si_note);
410411
knlist_destroy(&wpipe->pipe_sel.si_note);
412+
crfree(pp->pp_owner);
411413
#ifdef MAC
412414
mac_pipe_destroy(pp);
413415
#endif
@@ -574,9 +576,20 @@ pipespace_new(struct pipe *cpipe, int size)
574576
size = round_page(size);
575577
buffer = (caddr_t) vm_map_min(pipe_map);
576578

579+
if (!chgpipecnt(cpipe->pipe_pair->pp_owner->cr_ruidinfo,
580+
size, lim_cur(curthread, RLIMIT_PIPEBUF))) {
581+
if (cpipe->pipe_buffer.buffer == NULL &&
582+
size > SMALL_PIPE_SIZE) {
583+
size = SMALL_PIPE_SIZE;
584+
goto retry;
585+
}
586+
return (ENOMEM);
587+
}
588+
577589
error = vm_map_find(pipe_map, NULL, 0, (vm_offset_t *)&buffer, size, 0,
578590
VMFS_ANY_SPACE, VM_PROT_RW, VM_PROT_RW, 0);
579591
if (error != KERN_SUCCESS) {
592+
chgpipecnt(cpipe->pipe_pair->pp_owner->cr_ruidinfo, -size, 0);
580593
if (cpipe->pipe_buffer.buffer == NULL &&
581594
size > SMALL_PIPE_SIZE) {
582595
size = SMALL_PIPE_SIZE;
@@ -1645,6 +1658,8 @@ pipe_free_kmem(struct pipe *cpipe)
16451658

16461659
if (cpipe->pipe_buffer.buffer != NULL) {
16471660
atomic_subtract_long(&amountpipekva, cpipe->pipe_buffer.size);
1661+
chgpipecnt(cpipe->pipe_pair->pp_owner->cr_uidinfo,
1662+
-cpipe->pipe_buffer.size, 0);
16481663
vm_map_remove(pipe_map,
16491664
(vm_offset_t)cpipe->pipe_buffer.buffer,
16501665
(vm_offset_t)cpipe->pipe_buffer.buffer + cpipe->pipe_buffer.size);
@@ -1731,6 +1746,7 @@ pipeclose(struct pipe *cpipe)
17311746
*/
17321747
if (ppipe->pipe_present == PIPE_FINALIZED) {
17331748
PIPE_UNLOCK(cpipe);
1749+
crfree(cpipe->pipe_pair->pp_owner);
17341750
#ifdef MAC
17351751
mac_pipe_destroy(pp);
17361752
#endif

sys/sys/pipe.h

+1
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ struct pipepair {
136136
struct pipe pp_wpipe;
137137
struct mtx pp_mtx;
138138
struct label *pp_label;
139+
struct ucred *pp_owner; /* to dec pipe usage count */
139140
};
140141

141142
#define PIPE_MTX(pipe) (&(pipe)->pipe_pair->pp_mtx)

sys/sys/resource.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,9 @@ struct __wrusage {
114114
#define RLIMIT_SWAP 12 /* swap used */
115115
#define RLIMIT_KQUEUES 13 /* kqueues allocated */
116116
#define RLIMIT_UMTXP 14 /* process-shared umtx */
117+
#define RLIMIT_PIPEBUF 15 /* pipes/fifos buffers */
117118

118-
#define RLIM_NLIMITS 15 /* number of resource limits */
119+
#define RLIM_NLIMITS 16 /* number of resource limits */
119120

120121
#define RLIM_INFINITY ((rlim_t)(((__uint64_t)1 << 63) - 1))
121122
#define RLIM_SAVED_MAX RLIM_INFINITY

sys/sys/resourcevar.h

+2
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ struct uidinfo {
121121
long ui_ptscnt; /* (b) number of pseudo-terminals */
122122
long ui_kqcnt; /* (b) number of kqueues */
123123
long ui_umtxcnt; /* (b) number of shared umtxs */
124+
long ui_pipecnt; /* (b) consumption of pipe buffers */
124125
uid_t ui_uid; /* (a) uid */
125126
u_int ui_ref; /* (b) reference count */
126127
#ifdef RACCT
@@ -142,6 +143,7 @@ int chgsbsize(struct uidinfo *uip, u_int *hiwat, u_int to,
142143
rlim_t maxval);
143144
int chgptscnt(struct uidinfo *uip, int diff, rlim_t maxval);
144145
int chgumtxcnt(struct uidinfo *uip, int diff, rlim_t maxval);
146+
int chgpipecnt(struct uidinfo *uip, int diff, rlim_t max);
145147
int kern_proc_setrlimit(struct thread *td, struct proc *p, u_int which,
146148
struct rlimit *limp);
147149
struct plimit

0 commit comments

Comments
 (0)