mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-09-18 22:14:16 +00:00
Merge patch series "pipe: Trivial cleanups"
K Prateek Nayak <kprateek.nayak@amd.com> says:
Based on the suggestion on the RFC, the treewide conversion of
references to pipe->{head,tail} from unsigned int to pipe_index_t has
been dropped for now. The series contains trivial cleanup suggested to
limit the nr_slots in pipe_resize_ring() to be covered between
pipe_index_t limits of pipe->{head,tail} and using pipe_buf() to remove
the open-coded usage of masks to access pipe buffer building on Linus'
cleanup of fs/fuse/dev.c in commit ebb0f38bb4
("fs/pipe: fix pipe
buffer index use in FUSE")
* patches from https://lore.kernel.org/r/20250307052919.34542-1-kprateek.nayak@amd.com:
fs/splice: Use pipe_buf() helper to retrieve pipe buffer
fs/pipe: Use pipe_buf() helper to retrieve pipe buffer
kernel/watch_queue: Use pipe_buf() to retrieve the pipe buffer
fs/pipe: Limit the slots in pipe_resize_ring()
Link: https://lore.kernel.org/r/20250307052919.34542-1-kprateek.nayak@amd.com
Signed-off-by: Christian Brauner <brauner@kernel.org>
This commit is contained in:
commit
3732d8f165
3 changed files with 24 additions and 36 deletions
13
fs/pipe.c
13
fs/pipe.c
|
@ -294,7 +294,6 @@ anon_pipe_read(struct kiocb *iocb, struct iov_iter *to)
|
|||
/* Read ->head with a barrier vs post_one_notification() */
|
||||
unsigned int head = smp_load_acquire(&pipe->head);
|
||||
unsigned int tail = pipe->tail;
|
||||
unsigned int mask = pipe->ring_size - 1;
|
||||
|
||||
#ifdef CONFIG_WATCH_QUEUE
|
||||
if (pipe->note_loss) {
|
||||
|
@ -321,7 +320,7 @@ anon_pipe_read(struct kiocb *iocb, struct iov_iter *to)
|
|||
#endif
|
||||
|
||||
if (!pipe_empty(head, tail)) {
|
||||
struct pipe_buffer *buf = &pipe->bufs[tail & mask];
|
||||
struct pipe_buffer *buf = pipe_buf(pipe, tail);
|
||||
size_t chars = buf->len;
|
||||
size_t written;
|
||||
int error;
|
||||
|
@ -477,8 +476,7 @@ anon_pipe_write(struct kiocb *iocb, struct iov_iter *from)
|
|||
was_empty = pipe_empty(head, pipe->tail);
|
||||
chars = total_len & (PAGE_SIZE-1);
|
||||
if (chars && !was_empty) {
|
||||
unsigned int mask = pipe->ring_size - 1;
|
||||
struct pipe_buffer *buf = &pipe->bufs[(head - 1) & mask];
|
||||
struct pipe_buffer *buf = pipe_buf(pipe, head - 1);
|
||||
int offset = buf->offset + buf->len;
|
||||
|
||||
if ((buf->flags & PIPE_BUF_FLAG_CAN_MERGE) &&
|
||||
|
@ -509,7 +507,6 @@ anon_pipe_write(struct kiocb *iocb, struct iov_iter *from)
|
|||
|
||||
head = pipe->head;
|
||||
if (!pipe_full(head, pipe->tail, pipe->max_usage)) {
|
||||
unsigned int mask = pipe->ring_size - 1;
|
||||
struct pipe_buffer *buf;
|
||||
struct page *page;
|
||||
int copied;
|
||||
|
@ -531,7 +528,7 @@ anon_pipe_write(struct kiocb *iocb, struct iov_iter *from)
|
|||
|
||||
pipe->head = head + 1;
|
||||
/* Insert it into the buffer array */
|
||||
buf = &pipe->bufs[head & mask];
|
||||
buf = pipe_buf(pipe, head);
|
||||
buf->page = page;
|
||||
buf->ops = &anon_pipe_buf_ops;
|
||||
buf->offset = 0;
|
||||
|
@ -1293,6 +1290,10 @@ int pipe_resize_ring(struct pipe_inode_info *pipe, unsigned int nr_slots)
|
|||
struct pipe_buffer *bufs;
|
||||
unsigned int head, tail, mask, n;
|
||||
|
||||
/* nr_slots larger than limits of pipe->{head,tail} */
|
||||
if (unlikely(nr_slots > (pipe_index_t)-1u))
|
||||
return -EINVAL;
|
||||
|
||||
bufs = kcalloc(nr_slots, sizeof(*bufs),
|
||||
GFP_KERNEL_ACCOUNT | __GFP_NOWARN);
|
||||
if (unlikely(!bufs))
|
||||
|
|
40
fs/splice.c
40
fs/splice.c
|
@ -200,7 +200,6 @@ ssize_t splice_to_pipe(struct pipe_inode_info *pipe,
|
|||
unsigned int spd_pages = spd->nr_pages;
|
||||
unsigned int tail = pipe->tail;
|
||||
unsigned int head = pipe->head;
|
||||
unsigned int mask = pipe->ring_size - 1;
|
||||
ssize_t ret = 0;
|
||||
int page_nr = 0;
|
||||
|
||||
|
@ -214,7 +213,7 @@ ssize_t splice_to_pipe(struct pipe_inode_info *pipe,
|
|||
}
|
||||
|
||||
while (!pipe_full(head, tail, pipe->max_usage)) {
|
||||
struct pipe_buffer *buf = &pipe->bufs[head & mask];
|
||||
struct pipe_buffer *buf = pipe_buf(pipe, head);
|
||||
|
||||
buf->page = spd->pages[page_nr];
|
||||
buf->offset = spd->partial[page_nr].offset;
|
||||
|
@ -247,7 +246,6 @@ ssize_t add_to_pipe(struct pipe_inode_info *pipe, struct pipe_buffer *buf)
|
|||
{
|
||||
unsigned int head = pipe->head;
|
||||
unsigned int tail = pipe->tail;
|
||||
unsigned int mask = pipe->ring_size - 1;
|
||||
int ret;
|
||||
|
||||
if (unlikely(!pipe->readers)) {
|
||||
|
@ -256,7 +254,7 @@ ssize_t add_to_pipe(struct pipe_inode_info *pipe, struct pipe_buffer *buf)
|
|||
} else if (pipe_full(head, tail, pipe->max_usage)) {
|
||||
ret = -EAGAIN;
|
||||
} else {
|
||||
pipe->bufs[head & mask] = *buf;
|
||||
*pipe_buf(pipe, head) = *buf;
|
||||
pipe->head = head + 1;
|
||||
return buf->len;
|
||||
}
|
||||
|
@ -447,11 +445,10 @@ static int splice_from_pipe_feed(struct pipe_inode_info *pipe, struct splice_des
|
|||
{
|
||||
unsigned int head = pipe->head;
|
||||
unsigned int tail = pipe->tail;
|
||||
unsigned int mask = pipe->ring_size - 1;
|
||||
int ret;
|
||||
|
||||
while (!pipe_empty(head, tail)) {
|
||||
struct pipe_buffer *buf = &pipe->bufs[tail & mask];
|
||||
struct pipe_buffer *buf = pipe_buf(pipe, tail);
|
||||
|
||||
sd->len = buf->len;
|
||||
if (sd->len > sd->total_len)
|
||||
|
@ -495,8 +492,7 @@ static int splice_from_pipe_feed(struct pipe_inode_info *pipe, struct splice_des
|
|||
static inline bool eat_empty_buffer(struct pipe_inode_info *pipe)
|
||||
{
|
||||
unsigned int tail = pipe->tail;
|
||||
unsigned int mask = pipe->ring_size - 1;
|
||||
struct pipe_buffer *buf = &pipe->bufs[tail & mask];
|
||||
struct pipe_buffer *buf = pipe_buf(pipe, tail);
|
||||
|
||||
if (unlikely(!buf->len)) {
|
||||
pipe_buf_release(pipe, buf);
|
||||
|
@ -690,7 +686,7 @@ iter_file_splice_write(struct pipe_inode_info *pipe, struct file *out,
|
|||
while (sd.total_len) {
|
||||
struct kiocb kiocb;
|
||||
struct iov_iter from;
|
||||
unsigned int head, tail, mask;
|
||||
unsigned int head, tail;
|
||||
size_t left;
|
||||
int n;
|
||||
|
||||
|
@ -711,12 +707,11 @@ iter_file_splice_write(struct pipe_inode_info *pipe, struct file *out,
|
|||
|
||||
head = pipe->head;
|
||||
tail = pipe->tail;
|
||||
mask = pipe->ring_size - 1;
|
||||
|
||||
/* build the vector */
|
||||
left = sd.total_len;
|
||||
for (n = 0; !pipe_empty(head, tail) && left && n < nbufs; tail++) {
|
||||
struct pipe_buffer *buf = &pipe->bufs[tail & mask];
|
||||
struct pipe_buffer *buf = pipe_buf(pipe, tail);
|
||||
size_t this_len = buf->len;
|
||||
|
||||
/* zero-length bvecs are not supported, skip them */
|
||||
|
@ -752,7 +747,7 @@ iter_file_splice_write(struct pipe_inode_info *pipe, struct file *out,
|
|||
/* dismiss the fully eaten buffers, adjust the partial one */
|
||||
tail = pipe->tail;
|
||||
while (ret) {
|
||||
struct pipe_buffer *buf = &pipe->bufs[tail & mask];
|
||||
struct pipe_buffer *buf = pipe_buf(pipe, tail);
|
||||
if (ret >= buf->len) {
|
||||
ret -= buf->len;
|
||||
buf->len = 0;
|
||||
|
@ -809,7 +804,7 @@ ssize_t splice_to_socket(struct pipe_inode_info *pipe, struct file *out,
|
|||
pipe_lock(pipe);
|
||||
|
||||
while (len > 0) {
|
||||
unsigned int head, tail, mask, bc = 0;
|
||||
unsigned int head, tail, bc = 0;
|
||||
size_t remain = len;
|
||||
|
||||
/*
|
||||
|
@ -846,10 +841,9 @@ ssize_t splice_to_socket(struct pipe_inode_info *pipe, struct file *out,
|
|||
|
||||
head = pipe->head;
|
||||
tail = pipe->tail;
|
||||
mask = pipe->ring_size - 1;
|
||||
|
||||
while (!pipe_empty(head, tail)) {
|
||||
struct pipe_buffer *buf = &pipe->bufs[tail & mask];
|
||||
struct pipe_buffer *buf = pipe_buf(pipe, tail);
|
||||
size_t seg;
|
||||
|
||||
if (!buf->len) {
|
||||
|
@ -894,7 +888,7 @@ ssize_t splice_to_socket(struct pipe_inode_info *pipe, struct file *out,
|
|||
len -= ret;
|
||||
tail = pipe->tail;
|
||||
while (ret > 0) {
|
||||
struct pipe_buffer *buf = &pipe->bufs[tail & mask];
|
||||
struct pipe_buffer *buf = pipe_buf(pipe, tail);
|
||||
size_t seg = min_t(size_t, ret, buf->len);
|
||||
|
||||
buf->offset += seg;
|
||||
|
@ -1725,7 +1719,6 @@ static int splice_pipe_to_pipe(struct pipe_inode_info *ipipe,
|
|||
struct pipe_buffer *ibuf, *obuf;
|
||||
unsigned int i_head, o_head;
|
||||
unsigned int i_tail, o_tail;
|
||||
unsigned int i_mask, o_mask;
|
||||
int ret = 0;
|
||||
bool input_wakeup = false;
|
||||
|
||||
|
@ -1747,9 +1740,7 @@ retry:
|
|||
pipe_double_lock(ipipe, opipe);
|
||||
|
||||
i_tail = ipipe->tail;
|
||||
i_mask = ipipe->ring_size - 1;
|
||||
o_head = opipe->head;
|
||||
o_mask = opipe->ring_size - 1;
|
||||
|
||||
do {
|
||||
size_t o_len;
|
||||
|
@ -1792,8 +1783,8 @@ retry:
|
|||
goto retry;
|
||||
}
|
||||
|
||||
ibuf = &ipipe->bufs[i_tail & i_mask];
|
||||
obuf = &opipe->bufs[o_head & o_mask];
|
||||
ibuf = pipe_buf(ipipe, i_tail);
|
||||
obuf = pipe_buf(opipe, o_head);
|
||||
|
||||
if (len >= ibuf->len) {
|
||||
/*
|
||||
|
@ -1862,7 +1853,6 @@ static ssize_t link_pipe(struct pipe_inode_info *ipipe,
|
|||
struct pipe_buffer *ibuf, *obuf;
|
||||
unsigned int i_head, o_head;
|
||||
unsigned int i_tail, o_tail;
|
||||
unsigned int i_mask, o_mask;
|
||||
ssize_t ret = 0;
|
||||
|
||||
/*
|
||||
|
@ -1873,9 +1863,7 @@ static ssize_t link_pipe(struct pipe_inode_info *ipipe,
|
|||
pipe_double_lock(ipipe, opipe);
|
||||
|
||||
i_tail = ipipe->tail;
|
||||
i_mask = ipipe->ring_size - 1;
|
||||
o_head = opipe->head;
|
||||
o_mask = opipe->ring_size - 1;
|
||||
|
||||
do {
|
||||
if (!opipe->readers) {
|
||||
|
@ -1896,8 +1884,8 @@ static ssize_t link_pipe(struct pipe_inode_info *ipipe,
|
|||
pipe_full(o_head, o_tail, opipe->max_usage))
|
||||
break;
|
||||
|
||||
ibuf = &ipipe->bufs[i_tail & i_mask];
|
||||
obuf = &opipe->bufs[o_head & o_mask];
|
||||
ibuf = pipe_buf(ipipe, i_tail);
|
||||
obuf = pipe_buf(opipe, o_head);
|
||||
|
||||
/*
|
||||
* Get a reference to this pipe buffer,
|
||||
|
|
|
@ -101,12 +101,11 @@ static bool post_one_notification(struct watch_queue *wqueue,
|
|||
struct pipe_inode_info *pipe = wqueue->pipe;
|
||||
struct pipe_buffer *buf;
|
||||
struct page *page;
|
||||
unsigned int head, tail, mask, note, offset, len;
|
||||
unsigned int head, tail, note, offset, len;
|
||||
bool done = false;
|
||||
|
||||
spin_lock_irq(&pipe->rd_wait.lock);
|
||||
|
||||
mask = pipe->ring_size - 1;
|
||||
head = pipe->head;
|
||||
tail = pipe->tail;
|
||||
if (pipe_full(head, tail, pipe->ring_size))
|
||||
|
@ -124,7 +123,7 @@ static bool post_one_notification(struct watch_queue *wqueue,
|
|||
memcpy(p + offset, n, len);
|
||||
kunmap_atomic(p);
|
||||
|
||||
buf = &pipe->bufs[head & mask];
|
||||
buf = pipe_buf(pipe, head);
|
||||
buf->page = page;
|
||||
buf->private = (unsigned long)wqueue;
|
||||
buf->ops = &watch_queue_pipe_buf_ops;
|
||||
|
@ -147,7 +146,7 @@ out:
|
|||
return done;
|
||||
|
||||
lost:
|
||||
buf = &pipe->bufs[(head - 1) & mask];
|
||||
buf = pipe_buf(pipe, head - 1);
|
||||
buf->flags |= PIPE_BUF_FLAG_LOSS;
|
||||
goto out;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue