From: Oleg Nesterov <oleg@redhat.com>
To: Mateusz Guzik <mjguzik@gmail.com>
Cc: kernel test robot <oliver.sang@intel.com>,
oe-lkp@lists.linux.dev, lkp@intel.com,
Christian Brauner <brauner@kernel.org>,
WangYuli <wangyuli@uniontech.com>,
linux-fsdevel@vger.kernel.org
Subject: Re: [linux-next:master] [pipe_read] aaec5a95d5: stress-ng.poll.ops_per_sec 11.1% regression
Date: Mon, 20 Jan 2025 15:43:39 +0100 [thread overview]
Message-ID: <20250120144338.GC7432@redhat.com> (raw)
In-Reply-To: <20250120124209.GB7432@redhat.com>
On 01/20, Oleg Nesterov wrote:
>
> But I'll recheck this logic once again tomorrow, perhaps I misread
> pipe_write() when I made this patch.
Meanwhile I wrote a stupid test-case below.
Without the patch
State: S (sleeping)
voluntary_ctxt_switches: 74
nonvoluntary_ctxt_switches: 5
State: S (sleeping)
voluntary_ctxt_switches: 4169
nonvoluntary_ctxt_switches: 5
finally release the buffer
wrote next char!
With the patch
State: S (sleeping)
voluntary_ctxt_switches: 74
nonvoluntary_ctxt_switches: 3
State: S (sleeping)
voluntary_ctxt_switches: 74
nonvoluntary_ctxt_switches: 3
finally release the buffer
wrote next char!
As you can see, without this patch pipe_read() wakes the writer up
4095 times for no reason, the writer burns a bit of CPU and blocks
again after wakeup until the last read(fd[0], &c, 1).
Oleg.
-------------------------------------------------------------------------------
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
#include <sys/ioctl.h>
#include <stdio.h>
#include <errno.h>
int main(void)
{
int fd[2], nb, cnt;
char cmd[1024], c;
assert(pipe(fd) == 0);
nb = 1; assert(ioctl(fd[1], FIONBIO, &nb) == 0);
while (write(fd[1], &c, 1) == 1);
assert(errno = -EAGAIN);
nb = 0; assert(ioctl(fd[1], FIONBIO, &nb) == 0);
// The pipe is full, the next write() will block.
sprintf(cmd, "grep -e State -e ctxt_switches /proc/%d/status", getpid());
if (!fork()) {
// wait until the parent sleeps in pipe_write()
usleep(10000);
system(cmd);
// trigger 4095 unnecessary wakeups
for (cnt = 0; cnt < 4095; ++cnt) {
assert(read(fd[0], &c, 1) == 1);
usleep(1000);
}
system(cmd);
// this should actually wake the writer
printf("finally release the buffer\n");
assert(read(fd[0], &c, 1) == 1);
return 0;
}
assert(write(fd[1], &c, 1) == 1);
printf("wrote next char!\n");
return 0;
}
next prev parent reply other threads:[~2025-01-20 14:44 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-01-20 6:57 [linux-next:master] [pipe_read] aaec5a95d5: stress-ng.poll.ops_per_sec 11.1% regression kernel test robot
2025-01-20 11:27 ` Mateusz Guzik
2025-01-20 12:22 ` Oleg Nesterov
2025-01-20 12:42 ` Oleg Nesterov
2025-01-20 14:43 ` Oleg Nesterov [this message]
2025-01-20 16:56 ` Mateusz Guzik
2025-01-20 20:31 ` Oleg Nesterov
2025-01-20 21:15 ` Mateusz Guzik
2025-01-23 12:56 ` Oleg Nesterov
2025-01-20 15:50 ` Oleg Nesterov
2025-01-22 8:43 ` Oliver Sang
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250120144338.GC7432@redhat.com \
--to=oleg@redhat.com \
--cc=brauner@kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=lkp@intel.com \
--cc=mjguzik@gmail.com \
--cc=oe-lkp@lists.linux.dev \
--cc=oliver.sang@intel.com \
--cc=wangyuli@uniontech.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.