Message ID | d01fc60c6a85cc4af87f6f88eb5017b83c181f4d.1690307717.git.tanyuan@tinylab.org |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:9010:0:b0:3e4:2afc:c1 with SMTP id l16csp2651357vqg; Tue, 25 Jul 2023 11:16:36 -0700 (PDT) X-Google-Smtp-Source: APBJJlHR1gkSFdglbdYg8bZZO/rJZbX5xWKLTNG8rntxeKMBc4eKVpfg2Tm3PnRjKRS0Gbi+eeWw X-Received: by 2002:a05:6402:10cf:b0:521:d368:1628 with SMTP id p15-20020a05640210cf00b00521d3681628mr3446424edu.16.1690308996184; Tue, 25 Jul 2023 11:16:36 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1690308996; cv=none; d=google.com; s=arc-20160816; b=s97eCc8ELqis8FLR6vD1wdHSkP1vH4wunUaGOiC6bXEAjdMpZ+yWUtLM+1RLvOne7v 6AwGqcixBkjSzlkktQuM64gYyilHj56SZUoMug64fSqKVAN7sf6DjIfAmC9jcFOHE6Ip FCPcfDlBqDvx1kFTiNdHWRv8ztXZdQ5bG2yjCuYBm7HP5a0B015wMa2K0+Nr/YhjX9+k VMRTh0C9A/KE6gZZlYj5Sa0yKdr6kJSAYb3ZqYchMrCKs51I4Fk7f9bLVj0P8PrsZR5P EpcK9N3EtL3mWubdx5/X26QYKG5tVDpubwbe0tXRIGpESPd4wQmJb9LgZjfa4qT2V2+O 1bHw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:feedback-id:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from; bh=hKJyTLjYjDCKRDZppN+mrOq8GL+TM7eTZLr6ng333Ac=; fh=4Cpblm3wSM4rkkZEwabgTF4Z1dGAqmqNRU4fr+t5W/s=; b=pPONqZOh+TCCLVakFGRZFv4x2h8tsi/bOECt6KO8IImSYyohnbaxtIxZW7QKcGO4dQ h//r7/KYVgbvPrxhrsu/CiQsvdQXzGSHk3suJSVhMEp7d6h8cMKhHSrh94WZ0eq+aQ4z 9jL+tCvbWpZVkHIsLF8pp0RuE+3j+U6j6ykEJcrpMzfLjVP5bnSCrBfwEA7pKQ+v/Kci cpwxOQZuHxbUMQjnyDFKnAOIIcHtTxsYAjpjdP8djPSP7rnTTkOc6TshEMIFDmJxIGx+ QbD5903mjn/Z4x/rTqg12KODRWWtnmbiR+bt81fJp6kEuTXR4QKud4E/udiK/dg5zAm4 MM2Q== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id a21-20020a50ff15000000b005217878c5fbsi8159295edu.674.2023.07.25.11.16.12; Tue, 25 Jul 2023 11:16:36 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232283AbjGYSBg (ORCPT <rfc822;kloczko.tomasz@gmail.com> + 99 others); Tue, 25 Jul 2023 14:01:36 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53110 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232289AbjGYSBd (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Tue, 25 Jul 2023 14:01:33 -0400 Received: from bg4.exmail.qq.com (bg4.exmail.qq.com [43.154.54.12]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 55E431FF2; Tue, 25 Jul 2023 11:01:29 -0700 (PDT) X-QQ-mid: bizesmtp70t1690308084t5vcw89e Received: from localhost.localdomain ( [42.242.128.198]) by bizesmtp.qq.com (ESMTP) with id ; Wed, 26 Jul 2023 02:01:23 +0800 (CST) X-QQ-SSF: 01200000000000403000B00A0000000 X-QQ-FEAT: ybg6K0M/reNhatuJAQj2pVlNYo7QSouh4qfAKOOGrsqpOAFklqw056+Ntmyga qaW+pewqcXh9WzeCoCMnFwpA5DYy9Z0WlEhvJmb7cIC8k7t9wsQ5yzxNpkuv9QJVbUflA/e qmM6U0pcIdjN3KNy/aecc5d7F3FJ1gXG0T+FskvW9g6BoH2kh9Tj5nR9To1heHtp60kbpGJ tKmfZeCL/sLwJV+N6GdH6zc4+C6AxKjgJx9j+RsW1/lcVafqDCflR76efmhm9Uz0mA3LB0L 7V1kxcINVYOZdQZ5V7Ls5Jhc61lZCfnxDzg67lQtU9pvGmjc9/AdvSnCEqoREdVZy/vn7lj wOh053nzx4vqPfIhG2qc8sLrgSGu9e2jDpfWYrnNBW0E2DLQXM= X-QQ-GoodBg: 0 X-BIZMAIL-ID: 15258818057665170873 From: Yuan Tan <tanyuan@tinylab.org> To: w@1wt.eu Cc: falcon@tinylab.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, Yuan Tan <tanyuan@tinylab.org> Subject: [PATCH 1/2] tools/nolibc: add pipe() support Date: Tue, 25 Jul 2023 14:01:21 -0400 Message-Id: <d01fc60c6a85cc4af87f6f88eb5017b83c181f4d.1690307717.git.tanyuan@tinylab.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <cover.1690307717.git.tanyuan@tinylab.org> References: <cover.1690307717.git.tanyuan@tinylab.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-QQ-SENDSIZE: 520 Feedback-ID: bizesmtp:tinylab.org:qybglogicsvrgz:qybglogicsvrgz5a-1 X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_BLOCKED,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1772417446398409997 X-GMAIL-MSGID: 1772417446398409997 |
Series |
tools/nolibc: add pipe() and its testcase
|
|
Commit Message
Yuan Tan
July 25, 2023, 6:01 p.m. UTC
pipe is crucial for shell.
Signed-off-by: Yuan Tan <tanyuan@tinylab.org>
---
tools/include/nolibc/sys.h | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
Comments
Hi, Yuan > pipe is crucial for shell. > As the syscall manpage[1] shows, pipe() is just one of the exceptions how may require two return registers in some platforms, e.g.: arch/mips/kernel/syscall.c * For historic reasons the pipe(2) syscall on MIPS has an unusual calling * convention. It returns results in registers $v0 / $v1 which means there * is no need for it to do verify the validity of a userspace pointer * argument. Historically that used to be expensive in Linux. These days * the performance advantage is negligible. */ asmlinkage int sysm_pipe(void) { int fd[2]; int error = do_pipe_flags(fd, 0); if (error) return error; current_pt_regs()->regs[3] = fd[1]; return fd[0]; } The other exceptions are getxpid(2), getxuid(2), and getxgid(2) on Alpha. Since we are able to use pipe2() for pipe() (introduced from early Linux 2.6.27, glibc 2.9) and use getpid+getppid for getxpid, getuid+geteuid for getxuid and getgid+getegit for getxgid. So, it is possible provide such pipe() as a wraper of pipe2() and getxpid, getxuid and getxgid as wrappers of their corresponding syscall pairs, then, no need to provide a second return value for all of the existing architectures, for example: #ifndef pipe int pipe(int pipefd[2]) { pipe2(pipefd, 0); } #endif And for mips: // may be in tools/include/nolibc/types.h ? struct fd_pair { long fd[2]; }; // tools/include/nolibc/arch-mips.h struct fd_pair pipe(void) { struct fd_pair fds; int pipefds[2]; pipe2(pipefds, 0); fds.fd[0] = pipefds[0]; fds.fd[1] = pipefds[1]; return fds; } To use such method, the test case should be changed too, perhaps an easier method is even only provide pipe2() for all and let users define their own pipe() if really required, we also need to change the test case. Best regards, Zhangjin [1]: https://man7.org/linux/man-pages/man2/syscall.2.html > Signed-off-by: Yuan Tan <tanyuan@tinylab.org> > --- > tools/include/nolibc/sys.h | 17 +++++++++++++++++ > 1 file changed, 17 insertions(+) > > diff --git a/tools/include/nolibc/sys.h b/tools/include/nolibc/sys.h > index 8bfe7db20b80..09841fc266fe 100644 > --- a/tools/include/nolibc/sys.h > +++ b/tools/include/nolibc/sys.h > @@ -752,6 +752,23 @@ int open(const char *path, int flags, ...) > } > > > +/* > + * int pipe(int pipefd[2]); > + */ > + > +static __attribute__((unused)) > +int sys_pipe(int pipefd[2]) > +{ > + return my_syscall1(__NR_pipe, pipefd); > +} > + > +static __attribute__((unused)) > +int pipe(int pipefd[2]) > +{ > + return __sysret(sys_pipe(pipefd)); > +} > + > + > /* > * int prctl(int option, unsigned long arg2, unsigned long arg3, > * unsigned long arg4, unsigned long arg5); > -- > 2.39.2
Hi Zhangjin, hi Yuan, On Fri, Jul 28, 2023 at 11:50:31PM +0800, Zhangjin Wu wrote: > Hi, Yuan > > > pipe is crucial for shell. > > > > As the syscall manpage[1] shows, pipe() is just one of the exceptions how > may require two return registers in some platforms, e.g.: > arch/mips/kernel/syscall.c > > * For historic reasons the pipe(2) syscall on MIPS has an unusual calling > * convention. It returns results in registers $v0 / $v1 which means there > * is no need for it to do verify the validity of a userspace pointer > * argument. Historically that used to be expensive in Linux. These days > * the performance advantage is negligible. > */ (...) Ah indeed! I vaguely remembered that I had left that one aside for some time but did not remember why. Now I remember that I couldn't handle the MIPS implementation by then while it used to be my primary target. > Since we are able to use pipe2() for pipe() (introduced from early Linux > 2.6.27, glibc 2.9) and use getpid+getppid for getxpid, getuid+geteuid > for getxuid and getgid+getegit for getxgid. > > So, it is possible provide such pipe() as a wraper of pipe2() and Indeed. > getxpid, getxuid and getxgid as wrappers of their corresponding syscall > pairs, I doubt anyone needs these ones, I didn't know them and do not even have their man page. Let's keep the focus on what developers really use. > then, no need to provide a second return value for all of the > existing architectures, for example: > > #ifndef pipe > int pipe(int pipefd[2]) > { > pipe2(pipefd, 0); > } > #endif > > And for mips: > > // may be in tools/include/nolibc/types.h ? > struct fd_pair { > long fd[2]; > }; > > // tools/include/nolibc/arch-mips.h > struct fd_pair pipe(void) > { > struct fd_pair fds; > int pipefds[2]; > > pipe2(pipefds, 0); > > fds.fd[0] = pipefds[0]; > fds.fd[1] = pipefds[1]; > > return fds; > } This one does not have the correct prototype for the function exposed to the user, pipe really is "int pipe(int pipefd[2])". Maybe you were thinking about sys_pipe() instead ? But since MIPS also has pipe2() now, there's no reason to make an exception. > To use such method, the test case should be changed too, perhaps an > easier method is even only provide pipe2() for all and let users define > their own pipe() if really required, we also need to change the test > case. No, we need to provide users with what they need to compile standard code. If we rely on pipe2() to deliver pipe(), that's fine. We can even do it per-arch if there are constraints but it seems to me that pipe2() is OK. Thanks, Willy
> Hi Zhangjin, hi Yuan, > > On Fri, Jul 28, 2023 at 11:50:31PM +0800, Zhangjin Wu wrote: > > Hi, Yuan > > > > > pipe is crucial for shell. > > > > > > > As the syscall manpage[1] shows, pipe() is just one of the exceptions how > > may require two return registers in some platforms, e.g.: > > arch/mips/kernel/syscall.c > > > > * For historic reasons the pipe(2) syscall on MIPS has an unusual calling > > * convention. It returns results in registers $v0 / $v1 which means there > > * is no need for it to do verify the validity of a userspace pointer > > * argument. Historically that used to be expensive in Linux. These days > > * the performance advantage is negligible. > > */ > (...) > > Ah indeed! I vaguely remembered that I had left that one aside for some > time but did not remember why. Now I remember that I couldn't handle the > MIPS implementation by then while it used to be my primary target. > Seems pipe() is the **only** one some architectures (except Alpha) return two values, and now we have pipe2(), so, it is ok for us to simply use pipe2() instead ;-) > > Since we are able to use pipe2() for pipe() (introduced from early Linux > > 2.6.27, glibc 2.9) and use getpid+getppid for getxpid, getuid+geteuid > > for getxuid and getgid+getegit for getxgid. > > > > So, it is possible provide such pipe() as a wraper of pipe2() and > > Indeed. > > > getxpid, getxuid and getxgid as wrappers of their corresponding syscall > > pairs, > > I doubt anyone needs these ones, I didn't know them and do not even > have their man page. Let's keep the focus on what developers really use. > Yeah. > > then, no need to provide a second return value for all of the > > existing architectures, for example: > > > > > > #ifndef pipe > > int pipe(int pipefd[2]) > > { > > pipe2(pipefd, 0); > > } > > #endif > > > > And for mips: > > > > // may be in tools/include/nolibc/types.h ? > > struct fd_pair { > > long fd[2]; > > }; > > > > // tools/include/nolibc/arch-mips.h > > struct fd_pair pipe(void) > > { [...] > > > > pipe2(pipefds, 0); [...] > > } > > This one does not have the correct prototype for the function exposed > to the user, pipe really is "int pipe(int pipefd[2])". Maybe you were > thinking about sys_pipe() instead ? But since MIPS also has pipe2() now, > there's no reason to make an exception. > Yes, pipe2() should be a better choice, but I have seen this sentence in syscall manpage [1]: /* On Alpha, IA-64, MIPS, SuperH, and SPARC/SPARC64, pipe() has the following prototype; see NOTES */ #include <unistd.h> struct fd_pair { long fd[2]; }; struct fd_pair pipe(void); If it is about syscall, then we are ok to align all of the architectures together to use "int pipe(int pipefd[2])", otherwise, it will be required to define them in their own arch-<ARCH>.h, just like some defined for arch-s390.h. [1]: https://www.man7.org/linux/man-pages/man2/pipe.2.html > > To use such method, the test case should be changed too, perhaps an > > easier method is even only provide pipe2() for all and let users define > > their own pipe() if really required, we also need to change the test > > case. > > No, we need to provide users with what they need to compile standard > code. If we rely on pipe2() to deliver pipe(), that's fine. We can even > do it per-arch if there are constraints but it seems to me that pipe2() > is OK. > Ok. Thanks, Zhangjin > Thanks, > Willy
On Sat, Jul 29, 2023 at 04:37:00PM +0800, Zhangjin Wu wrote: > > This one does not have the correct prototype for the function exposed > > to the user, pipe really is "int pipe(int pipefd[2])". Maybe you were > > thinking about sys_pipe() instead ? But since MIPS also has pipe2() now, > > there's no reason to make an exception. > > > > Yes, pipe2() should be a better choice, but I have seen this sentence in > syscall manpage [1]: > > /* On Alpha, IA-64, MIPS, SuperH, and SPARC/SPARC64, pipe() has the > following prototype; see NOTES */ > > #include <unistd.h> > > struct fd_pair { > long fd[2]; > }; > struct fd_pair pipe(void); > > If it is about syscall, then we are ok to align all of the architectures > together to use "int pipe(int pipefd[2])" Yes it's OK, that's how applications expect it to be used: https://pubs.opengroup.org/onlinepubs/9699919799/functions/pipe.html For the archs you mention above, it's the libc that wraps the call, exactly what we ought to do as well (using pipe2() since it will be easier). Willy
diff --git a/tools/include/nolibc/sys.h b/tools/include/nolibc/sys.h index 8bfe7db20b80..09841fc266fe 100644 --- a/tools/include/nolibc/sys.h +++ b/tools/include/nolibc/sys.h @@ -752,6 +752,23 @@ int open(const char *path, int flags, ...) } +/* + * int pipe(int pipefd[2]); + */ + +static __attribute__((unused)) +int sys_pipe(int pipefd[2]) +{ + return my_syscall1(__NR_pipe, pipefd); +} + +static __attribute__((unused)) +int pipe(int pipefd[2]) +{ + return __sysret(sys_pipe(pipefd)); +} + + /* * int prctl(int option, unsigned long arg2, unsigned long arg3, * unsigned long arg4, unsigned long arg5);