Skip to content

Commit 5953522

Browse files
committed
Merge: fs: improve fd allocation performance
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-9/-/merge_requests/6976 JIRA: https://issues.redhat.com/browse/RHEL-38570 Upstream status: Linus Back port patch series that improves the performance of fd allocation performance quite a bit. See comment in the MR for more information about why I omitted it. Omitted-Fix: dc530c4 ("fs: use debug-only asserts around fd allocation and install") Signed-off-by: Ian Kent <ikent@redhat.com> Approved-by: Brian Foster <bfoster@redhat.com> Approved-by: Miklos Szeredi <mszeredi@redhat.com> Approved-by: David Howells <dhowells@redhat.com> Approved-by: CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> Merged-by: Augusto Caringi <acaringi@redhat.com>
2 parents 638423b + 773faed commit 5953522

File tree

1 file changed

+26
-20
lines changed

1 file changed

+26
-20
lines changed

fs/file.c

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,9 @@ static inline void __set_open_fd(unsigned int fd, struct fdtable *fdt)
252252
static inline void __clear_open_fd(unsigned int fd, struct fdtable *fdt)
253253
{
254254
__clear_bit(fd, fdt->open_fds);
255-
__clear_bit(fd / BITS_PER_LONG, fdt->full_fds_bits);
255+
fd /= BITS_PER_LONG;
256+
if (test_bit(fd, fdt->full_fds_bits))
257+
__clear_bit(fd, fdt->full_fds_bits);
256258
}
257259

258260
static unsigned int count_open_files(struct fdtable *fdt)
@@ -455,6 +457,15 @@ static unsigned int find_next_fd(struct fdtable *fdt, unsigned int start)
455457
unsigned int maxfd = fdt->max_fds;
456458
unsigned int maxbit = maxfd / BITS_PER_LONG;
457459
unsigned int bitbit = start / BITS_PER_LONG;
460+
unsigned int bit;
461+
462+
/*
463+
* Try to avoid looking at the second level bitmap
464+
*/
465+
bit = find_next_zero_bit(&fdt->open_fds[bitbit], BITS_PER_LONG,
466+
start & (BITS_PER_LONG - 1));
467+
if (bit < BITS_PER_LONG)
468+
return bit + bitbit * BITS_PER_LONG;
458469

459470
bitbit = find_next_zero_bit(fdt->full_fds_bits, maxbit, bitbit) * BITS_PER_LONG;
460471
if (bitbit > maxfd)
@@ -481,27 +492,29 @@ static int alloc_fd(unsigned start, unsigned end, unsigned flags)
481492
if (fd < files->next_fd)
482493
fd = files->next_fd;
483494

484-
if (fd < fdt->max_fds)
495+
if (likely(fd < fdt->max_fds))
485496
fd = find_next_fd(fdt, fd);
486497

487498
/*
488499
* N.B. For clone tasks sharing a files structure, this test
489500
* will limit the total number of files that can be opened.
490501
*/
491502
error = -EMFILE;
492-
if (fd >= end)
503+
if (unlikely(fd >= end))
493504
goto out;
494505

495-
error = expand_files(files, fd);
496-
if (error < 0)
497-
goto out;
506+
if (unlikely(fd >= fdt->max_fds)) {
507+
error = expand_files(files, fd);
508+
if (error < 0)
509+
goto out;
498510

499-
/*
500-
* If we needed to expand the fs array we
501-
* might have blocked - try again.
502-
*/
503-
if (error)
504-
goto repeat;
511+
/*
512+
* If we needed to expand the fs array we
513+
* might have blocked - try again.
514+
*/
515+
if (error)
516+
goto repeat;
517+
}
505518

506519
if (start <= files->next_fd)
507520
files->next_fd = fd + 1;
@@ -512,13 +525,6 @@ static int alloc_fd(unsigned start, unsigned end, unsigned flags)
512525
else
513526
__clear_close_on_exec(fd, fdt);
514527
error = fd;
515-
#if 1
516-
/* Sanity check */
517-
if (rcu_access_pointer(fdt->fd[fd]) != NULL) {
518-
printk(KERN_WARNING "alloc_fd: slot %d not NULL!\n", fd);
519-
rcu_assign_pointer(fdt->fd[fd], NULL);
520-
}
521-
#endif
522528

523529
out:
524530
spin_unlock(&files->file_lock);
@@ -581,7 +587,7 @@ void fd_install(unsigned int fd, struct file *file)
581587
rcu_read_unlock_sched();
582588
spin_lock(&files->file_lock);
583589
fdt = files_fdtable(files);
584-
BUG_ON(fdt->fd[fd] != NULL);
590+
WARN_ON(fdt->fd[fd] != NULL);
585591
rcu_assign_pointer(fdt->fd[fd], file);
586592
spin_unlock(&files->file_lock);
587593
return;

0 commit comments

Comments
 (0)