linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* Re: [PATCH] ipc/msg: add msgsnd_timed and msgrcv_timed syscall for system V message queue
       [not found] <tencent_2CB9BD7D4063DE3F6845F79176B2D29A7E09@qq.com>
@ 2021-02-28 15:38 ` Arnd Bergmann
       [not found]   ` <tencent_2B7E37BD494059DF7D6845F641769CD28209@qq.com>
  0 siblings, 1 reply; 4+ messages in thread
From: Arnd Bergmann @ 2021-02-28 15:38 UTC (permalink / raw)
  To: Eric Gao
  Cc: dalias, benh, James Bottomley, jcmvbkbc, paulus, hpa, will,
	linux-arch, arnd, ysato, mpe, deller, borntraeger, mingo, geert,
	catalin.marinas, gor, hca, bp, luto, tglx, linux-arm-kernel,
	chris, monstr, tsbogend, linux-api, linux-kernel, linux-alpha,
	davem

On Sun, Feb 28, 2021 at 4:16 PM Eric Gao <eric.tech@foxmail.com> wrote:
>
> Hi Arnd:
>
>             Thanks for your kindly reply.
>
>             I want to prove you and all of others that these syscalls are very useful and necessary. Actually,  I add these syscalls
>
>     when I try to implement the local rpc by system v message queue (some people might think I am crazy to using message
>
>     queue, but it's truly a very efficient method than socket except it don't have a time-controlled msgrcv syscall).

(note: please don't reply in html)

>             In addition,  msgrcv_timed is also necessary in usual bidirection communication.  For example:
> A send a message to B, and try to receive a reply  from B  by msgrcv syscall.  But A need to do
> something else in case of  that B has terminated. So
>
>     we need the msgrcv syscall return after a preset time. The similar syscall can be found in
> posix message queue(mq_timedreceive)  and in z/OS system of
>  IBM(https://www.ibm.com/support/knowledgecenter/en/SSLTBW_2.2.0/com.ibm.zos.v2r2.bpxbd00/msgrcvt.htm).
>
>   And when I search the web, I can find that many people need such like syscall in their
> applications. so I hope this patch can be merged into the mainline, Thanks a lot.

It might help to add some explanation on why you need to add the timeout
to the old sysv message queues, when the more modern posix message
queues already support this.

Is there something that mq_timedsend/mq_timedreceive cannot do that
you need? Would it be possible to add that feature to the posix message
queues instead?

> +COMPAT_SYSCALL_DEFINE5(msgsnd_timed, int, msqid, compat_uptr_t, msgp,
> +                      compat_ssize_t, msgsz, int, msgflg, compat_long_t, timeoutms)
> +{
> +       struct compat_msgbuf __user *up = compat_ptr(msgp);
> +       compat_long_t mtype;
> +
> +       timeoutms = (timeoutms + 9) / 10;
> +
> +       if (get_user(mtype, &up->mtype))
> +               return -EFAULT;
> +
> +       return do_msgsnd(msqid, mtype, up->mtext, (ssize_t)msgsz, msgflg, (long)timeoutms);
> +}
>
> My preference would be to simplify both the timed and non-timed version by
> moving the get_user() into do_msgsnd() and using in_compat_task() to pick
> the right type. Same for the receive side of course. If you do this,
> watch out for x32 support, which uses the 64-bit version.
>
>     Actually, the timed and non-timed version have different number of
>  parameter(timed version have timeoutms), so I don't
> think they can be combine together,  and I don't want to impact the
> applications which  have been using the old style msgrcv syscall.

What I meant was combining the implementation of the native and
compat versions, not combining the timed and non-timed versions,
which you already do to the degree possible.

           Arnd

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] ipc/msg: add msgsnd_timed and msgrcv_timed syscall for system V message queue
       [not found]   ` <tencent_2B7E37BD494059DF7D6845F641769CD28209@qq.com>
@ 2021-02-28 19:49     ` Arnd Bergmann
  0 siblings, 0 replies; 4+ messages in thread
From: Arnd Bergmann @ 2021-02-28 19:49 UTC (permalink / raw)
  To: Eric Gao
  Cc: dalias, benh, James Bottomley, jcmvbkbc, paulus, hpa, will,
	linux-arch, arnd, ysato, mpe, deller, borntraeger, mingo, geert,
	catalin.marinas, gor, hca, bp, luto, tglx, linux-arm-kernel,
	chris, monstr, tsbogend, linux-api, linux-kernel, linux-alpha,
	davem

On Sun, Feb 28, 2021 at 5:16 PM Eric Gao <eric.tech@foxmail.com> wrote:
>
> > Is there something that mq_timedsend/mq_timedreceive cannot do that
> > you need? Would it be possible to add that feature to the posix message
> > queues instead?
>
> the system v message queue have a mtype parameter both in msgsnd and msgrcv which can be
> used to implement message routing(mtype as the target id. For example, I filling the target thread
> id that waiting message). It's the most important.
>
> but mq_timedsend/mq_timedreceive in posix message queue don't have this feature.

I'm not sure I'm following here. With posix message queues, can't you just open
one queue per target thread? That would seem simpler and more efficient besides
also allowing the timeout.

         Arnd

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] ipc/msg: add msgsnd_timed and msgrcv_timed syscall for system V message queue
  2021-02-27  6:52 Eric Gao
@ 2021-02-27 12:29 ` Arnd Bergmann
  0 siblings, 0 replies; 4+ messages in thread
From: Arnd Bergmann @ 2021-02-27 12:29 UTC (permalink / raw)
  To: Eric Gao
  Cc: Rich Felker, Benjamin Herrenschmidt, James Bottomley,
	Max Filippov, Paul Mackerras, H. Peter Anvin, Will Deacon,
	linux-arch, Arnd Bergmann, Yoshinori Sato, Michael Ellerman,
	Helge Deller, Christian Borntraeger, Ingo Molnar,
	Geert Uytterhoeven, Catalin Marinas, Vasily Gorbik,
	Heiko Carstens, Borislav Petkov, Andy Lutomirski,
	Thomas Gleixner, Linux ARM, Chris Zankel, Michal Simek,
	Thomas Bogendoerfer, Linux API, linux-kernel, alpha,
	David Miller

On Sat, Feb 27, 2021 at 7:52 AM Eric Gao <eric.tech@foxmail.com> wrote:
>
> sometimes, we need the msgsnd or msgrcv syscall can return after a limited
> time, so that the business thread do not be blocked here all the time. In
> this case, I add the msgsnd_timed and msgrcv_timed syscall that with time
> parameter, which has a unit of ms.
>
> Signed-off-by: Eric Gao <eric.tech@foxmail.com>

I have no opinion on whether we want or need this, but I'll have a look
at the implementation, to see if the ABI makes sense.

> index 8fd8c17..42b7db5 100644
> --- a/arch/mips/kernel/syscalls/syscall_n32.tbl
> +++ b/arch/mips/kernel/syscalls/syscall_n32.tbl
> @@ -381,3 +381,5 @@
>  440    n32     process_madvise                 sys_process_madvise
>  441    n32     epoll_pwait2                    compat_sys_epoll_pwait2
>  442    n32     mount_setattr                   sys_mount_setattr
> +443    n32     msgrcv_timed                    sys_msgrcv_timed
> +444    n32     msgsnd_timed                    sys_msgsnd_timed
> diff --git a/arch/mips/kernel/syscalls/syscall_o32.tbl b/arch/mips/kernel/syscalls/syscall_o32.tbl
> index 090d29c..0f1f6ee 100644
> --- a/arch/mips/kernel/syscalls/syscall_o32.tbl
> +++ b/arch/mips/kernel/syscalls/syscall_o32.tbl
> @@ -430,3 +430,5 @@
>  440    o32     process_madvise                 sys_process_madvise
>  441    o32     epoll_pwait2                    sys_epoll_pwait2                compat_sys_epoll_pwait2
>  442    o32     mount_setattr                   sys_mount_setattr
> +443    o32     msgrcv_timed                    sys_msgrcv_timed
> +444    o32     msgsnd_timed                    sys_msgsnd_timed

I think mips n32 and o32 both need to use the compat version when running on
a 64-bit kernel, while your patch makes them use the native version.

> @@ -905,7 +906,15 @@ static long do_msgsnd(int msqid, long mtype, void __user *mtext,
>
>                 ipc_unlock_object(&msq->q_perm);
>                 rcu_read_unlock();
> -               schedule();
> +
> +               /* sometimes, we need msgsnd syscall return after a given time */
> +               if (timeoutms <= 0) {
> +                       schedule();
> +               } else {
> +                       timeoutms = schedule_timeout(timeoutms);
> +                       if (timeoutms == 0)
> +                               timeoutflag = true;
> +               }

I wonder if this should be schedule_timeout_interruptible() or at least
schedule_timeout_killable() instead of schedule_timeout(). If it should,
this should probably be done as a separate change.

> +COMPAT_SYSCALL_DEFINE5(msgsnd_timed, int, msqid, compat_uptr_t, msgp,
> +                      compat_ssize_t, msgsz, int, msgflg, compat_long_t, timeoutms)
> +{
> +       struct compat_msgbuf __user *up = compat_ptr(msgp);
> +       compat_long_t mtype;
> +
> +       timeoutms = (timeoutms + 9) / 10;
> +
> +       if (get_user(mtype, &up->mtype))
> +               return -EFAULT;
> +
> +       return do_msgsnd(msqid, mtype, up->mtext, (ssize_t)msgsz, msgflg, (long)timeoutms);
> +}

My preference would be to simplify both the timed and non-timed version by
moving the get_user() into do_msgsnd() and using in_compat_task() to pick
the right type. Same for the receive side of course. If you do this,
watch out for
x32 support, which uses the 64-bit version.

       Arnd

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH] ipc/msg: add msgsnd_timed and msgrcv_timed syscall for system V message queue
@ 2021-02-27  6:52 Eric Gao
  2021-02-27 12:29 ` Arnd Bergmann
  0 siblings, 1 reply; 4+ messages in thread
From: Eric Gao @ 2021-02-27  6:52 UTC (permalink / raw)
  To: catalin.marinas, will, geert, monstr, tsbogend, James.Bottomley,
	deller, mpe, hca, gor, borntraeger, ysato, dalias, davem, luto,
	tglx, mingo, bp, chris, jcmvbkbc, arnd, benh, paulus, hpa,
	eric.tech
  Cc: linux-arch, linux-api, linux-kernel, linux-arm-kernel, linux-alpha

sometimes, we need the msgsnd or msgrcv syscall can return after a limited
time, so that the business thread do not be blocked here all the time. In
this case, I add the msgsnd_timed and msgrcv_timed syscall that with time
parameter, which has a unit of ms.

Signed-off-by: Eric Gao <eric.tech@foxmail.com>
---
 arch/alpha/kernel/syscalls/syscall.tbl      |  2 +
 arch/arm/tools/syscall.tbl                  |  2 +
 arch/arm64/include/asm/unistd.h             |  2 +-
 arch/arm64/include/asm/unistd32.h           |  4 ++
 arch/ia64/kernel/syscalls/syscall.tbl       |  2 +
 arch/m68k/kernel/syscalls/syscall.tbl       |  2 +
 arch/microblaze/kernel/syscalls/syscall.tbl |  2 +
 arch/mips/kernel/syscalls/syscall_n32.tbl   |  2 +
 arch/mips/kernel/syscalls/syscall_n64.tbl   |  2 +
 arch/mips/kernel/syscalls/syscall_o32.tbl   |  2 +
 arch/parisc/kernel/syscalls/syscall.tbl     |  2 +
 arch/powerpc/kernel/syscalls/syscall.tbl    |  2 +
 arch/s390/kernel/syscalls/syscall.tbl       |  2 +
 arch/sh/kernel/syscalls/syscall.tbl         |  2 +
 arch/sparc/kernel/syscalls/syscall.tbl      |  2 +
 arch/x86/entry/syscalls/syscall_32.tbl      |  2 +
 arch/x86/entry/syscalls/syscall_64.tbl      |  2 +
 arch/xtensa/kernel/syscalls/syscall.tbl     |  2 +
 include/linux/compat.h                      |  4 ++
 include/linux/syscalls.h                    |  4 ++
 include/uapi/asm-generic/unistd.h           |  6 +-
 ipc/msg.c                                   | 87 ++++++++++++++++++++++++++---
 kernel/sys_ni.c                             |  4 ++
 23 files changed, 133 insertions(+), 10 deletions(-)

diff --git a/arch/alpha/kernel/syscalls/syscall.tbl b/arch/alpha/kernel/syscalls/syscall.tbl
index 02f0244..eed8cc6 100644
--- a/arch/alpha/kernel/syscalls/syscall.tbl
+++ b/arch/alpha/kernel/syscalls/syscall.tbl
@@ -482,3 +482,5 @@
 550	common	process_madvise			sys_process_madvise
 551	common	epoll_pwait2			sys_epoll_pwait2
 552	common	mount_setattr			sys_mount_setattr
+553	common	msgrcv_timed			sys_msgrcv_timed
+554	common	msgsnd_timed			sys_msgsnd_timed
diff --git a/arch/arm/tools/syscall.tbl b/arch/arm/tools/syscall.tbl
index dcc1191..c16baa6 100644
--- a/arch/arm/tools/syscall.tbl
+++ b/arch/arm/tools/syscall.tbl
@@ -456,3 +456,5 @@
 440	common	process_madvise			sys_process_madvise
 441	common	epoll_pwait2			sys_epoll_pwait2
 442	common	mount_setattr			sys_mount_setattr
+443	common	msgrcv_timed			sys_msgrcv_timed
+444	common  msgsnd_timed			sys_msgsnd_timed
diff --git a/arch/arm64/include/asm/unistd.h b/arch/arm64/include/asm/unistd.h
index 949788f..64ebdc1e 100644
--- a/arch/arm64/include/asm/unistd.h
+++ b/arch/arm64/include/asm/unistd.h
@@ -38,7 +38,7 @@
 #define __ARM_NR_compat_set_tls		(__ARM_NR_COMPAT_BASE + 5)
 #define __ARM_NR_COMPAT_END		(__ARM_NR_COMPAT_BASE + 0x800)
 
-#define __NR_compat_syscalls		443
+#define __NR_compat_syscalls		445
 #endif
 
 #define __ARCH_WANT_SYS_CLONE
diff --git a/arch/arm64/include/asm/unistd32.h b/arch/arm64/include/asm/unistd32.h
index 3d874f6..705676a 100644
--- a/arch/arm64/include/asm/unistd32.h
+++ b/arch/arm64/include/asm/unistd32.h
@@ -893,6 +893,10 @@ __SYSCALL(__NR_process_madvise, sys_process_madvise)
 __SYSCALL(__NR_epoll_pwait2, compat_sys_epoll_pwait2)
 #define __NR_mount_setattr 442
 __SYSCALL(__NR_mount_setattr, sys_mount_setattr)
+#define __NR_msgrcv_timed 443
+__SYSCALL(__NR_msgrcv_timed, sys_msgrcv_timed)
+#define __NR_msgsnd_timed 444
+__SYSCALL(__NR_msgsnd_timed, sys_msgsnd_timed)
 
 /*
  * Please add new compat syscalls above this comment and update
diff --git a/arch/ia64/kernel/syscalls/syscall.tbl b/arch/ia64/kernel/syscalls/syscall.tbl
index d892311..ad57e6d 100644
--- a/arch/ia64/kernel/syscalls/syscall.tbl
+++ b/arch/ia64/kernel/syscalls/syscall.tbl
@@ -363,3 +363,5 @@
 440	common	process_madvise			sys_process_madvise
 441	common	epoll_pwait2			sys_epoll_pwait2
 442	common	mount_setattr			sys_mount_setattr
+443	common  msgrcv_timed			sys_msgrcv_timed
+444	common  msgsnd_timed			sys_msgsnd_timed
diff --git a/arch/m68k/kernel/syscalls/syscall.tbl b/arch/m68k/kernel/syscalls/syscall.tbl
index 72bde67..1d33825 100644
--- a/arch/m68k/kernel/syscalls/syscall.tbl
+++ b/arch/m68k/kernel/syscalls/syscall.tbl
@@ -442,3 +442,5 @@
 440	common	process_madvise			sys_process_madvise
 441	common	epoll_pwait2			sys_epoll_pwait2
 442	common	mount_setattr			sys_mount_setattr
+443	common	msgrcv_timed			sys_msgrcv_timed
+444	common	msgsnd_timed			sys_msgsnd_timed
diff --git a/arch/microblaze/kernel/syscalls/syscall.tbl b/arch/microblaze/kernel/syscalls/syscall.tbl
index d603a5e..38d7f7a 100644
--- a/arch/microblaze/kernel/syscalls/syscall.tbl
+++ b/arch/microblaze/kernel/syscalls/syscall.tbl
@@ -448,3 +448,5 @@
 440	common	process_madvise			sys_process_madvise
 441	common	epoll_pwait2			sys_epoll_pwait2
 442	common	mount_setattr			sys_mount_setattr
+443	common	msgrcv_timed			sys_msgrcv_timed
+444	common	msgsnd_timed			sys_msgsnd_timed
diff --git a/arch/mips/kernel/syscalls/syscall_n32.tbl b/arch/mips/kernel/syscalls/syscall_n32.tbl
index 8fd8c17..42b7db5 100644
--- a/arch/mips/kernel/syscalls/syscall_n32.tbl
+++ b/arch/mips/kernel/syscalls/syscall_n32.tbl
@@ -381,3 +381,5 @@
 440	n32	process_madvise			sys_process_madvise
 441	n32	epoll_pwait2			compat_sys_epoll_pwait2
 442	n32	mount_setattr			sys_mount_setattr
+443	n32	msgrcv_timed			sys_msgrcv_timed
+444	n32	msgsnd_timed			sys_msgsnd_timed
diff --git a/arch/mips/kernel/syscalls/syscall_n64.tbl b/arch/mips/kernel/syscalls/syscall_n64.tbl
index 169f214..060208b 100644
--- a/arch/mips/kernel/syscalls/syscall_n64.tbl
+++ b/arch/mips/kernel/syscalls/syscall_n64.tbl
@@ -357,3 +357,5 @@
 440	n64	process_madvise			sys_process_madvise
 441	n64	epoll_pwait2			sys_epoll_pwait2
 442	n64	mount_setattr			sys_mount_setattr
+443	n64	msgrcv_timed			sys_msgrcv_timed
+444	n64	msgsnd_timed			sys_msgsnd_timed
diff --git a/arch/mips/kernel/syscalls/syscall_o32.tbl b/arch/mips/kernel/syscalls/syscall_o32.tbl
index 090d29c..0f1f6ee 100644
--- a/arch/mips/kernel/syscalls/syscall_o32.tbl
+++ b/arch/mips/kernel/syscalls/syscall_o32.tbl
@@ -430,3 +430,5 @@
 440	o32	process_madvise			sys_process_madvise
 441	o32	epoll_pwait2			sys_epoll_pwait2		compat_sys_epoll_pwait2
 442	o32	mount_setattr			sys_mount_setattr
+443	o32	msgrcv_timed			sys_msgrcv_timed
+444	o32	msgsnd_timed			sys_msgsnd_timed
diff --git a/arch/parisc/kernel/syscalls/syscall.tbl b/arch/parisc/kernel/syscalls/syscall.tbl
index 271a925..fef5544 100644
--- a/arch/parisc/kernel/syscalls/syscall.tbl
+++ b/arch/parisc/kernel/syscalls/syscall.tbl
@@ -440,3 +440,5 @@
 440	common	process_madvise			sys_process_madvise
 441	common	epoll_pwait2			sys_epoll_pwait2		compat_sys_epoll_pwait2
 442	common	mount_setattr			sys_mount_setattr
+443	common	msgrcv_timed			sys_msgrcv_timed		compat_sys_msgrcv_timed
+444	common	msgsnd_timed			sys_msgsnd_timed		compat_sys_msgsnd_timed
diff --git a/arch/powerpc/kernel/syscalls/syscall.tbl b/arch/powerpc/kernel/syscalls/syscall.tbl
index 0b2480c..115217c 100644
--- a/arch/powerpc/kernel/syscalls/syscall.tbl
+++ b/arch/powerpc/kernel/syscalls/syscall.tbl
@@ -522,3 +522,5 @@
 440	common	process_madvise			sys_process_madvise
 441	common	epoll_pwait2			sys_epoll_pwait2		compat_sys_epoll_pwait2
 442	common	mount_setattr			sys_mount_setattr
+443	common	msgrcv_timed			sys_msgrcv_timed		compat_sys_msgrcv_timed
+444	common	msgsnd_timed			sys_msgsnd_timed		compat_sys_msgsnd_timed
diff --git a/arch/s390/kernel/syscalls/syscall.tbl b/arch/s390/kernel/syscalls/syscall.tbl
index 3abef21..863b992 100644
--- a/arch/s390/kernel/syscalls/syscall.tbl
+++ b/arch/s390/kernel/syscalls/syscall.tbl
@@ -445,3 +445,5 @@
 440  common	process_madvise		sys_process_madvise		sys_process_madvise
 441  common	epoll_pwait2		sys_epoll_pwait2		compat_sys_epoll_pwait2
 442  common	mount_setattr		sys_mount_setattr		sys_mount_setattr
+443  common	msgrcv_timed		sys_msgrcv_timed		compat_sys_msgrcv_timed
+444  common	msgsnd_timed		sys_msgsnd_timed		compat_sys_msgsnd_timed
diff --git a/arch/sh/kernel/syscalls/syscall.tbl b/arch/sh/kernel/syscalls/syscall.tbl
index d08eeba..24245c0 100644
--- a/arch/sh/kernel/syscalls/syscall.tbl
+++ b/arch/sh/kernel/syscalls/syscall.tbl
@@ -445,3 +445,5 @@
 440	common	process_madvise			sys_process_madvise
 441	common	epoll_pwait2			sys_epoll_pwait2
 442	common	mount_setattr			sys_mount_setattr
+443	common	msgrcv_timed			sys_msgrcv_timed
+444	common	msgsnd_timed			sys_msgsnd_timed
diff --git a/arch/sparc/kernel/syscalls/syscall.tbl b/arch/sparc/kernel/syscalls/syscall.tbl
index 84403a9..d35e062 100644
--- a/arch/sparc/kernel/syscalls/syscall.tbl
+++ b/arch/sparc/kernel/syscalls/syscall.tbl
@@ -488,3 +488,5 @@
 440	common	process_madvise			sys_process_madvise
 441	common	epoll_pwait2			sys_epoll_pwait2		compat_sys_epoll_pwait2
 442	common	mount_setattr			sys_mount_setattr
+443	common	msgrcv_timed			sys_msgrcv_timed		compat_sys_msgrcv_timed
+444	common	msgsnd_timed			sys_msgsnd_timed		compat_sys_msgsnd_timed
diff --git a/arch/x86/entry/syscalls/syscall_32.tbl b/arch/x86/entry/syscalls/syscall_32.tbl
index a1c9f496f..6adc251 100644
--- a/arch/x86/entry/syscalls/syscall_32.tbl
+++ b/arch/x86/entry/syscalls/syscall_32.tbl
@@ -447,3 +447,5 @@
 440	i386	process_madvise		sys_process_madvise
 441	i386	epoll_pwait2		sys_epoll_pwait2		compat_sys_epoll_pwait2
 442	i386	mount_setattr		sys_mount_setattr
+443	i386	msgrcv_timed		sys_msgrcv_timed		compat_sys_msgrcv_timed
+444	i386	msgsnd_timed		sys_msgsnd_timed		compat_sys_msgsnd_timed
diff --git a/arch/x86/entry/syscalls/syscall_64.tbl b/arch/x86/entry/syscalls/syscall_64.tbl
index 7bf01cb..44e4c63 100644
--- a/arch/x86/entry/syscalls/syscall_64.tbl
+++ b/arch/x86/entry/syscalls/syscall_64.tbl
@@ -364,6 +364,8 @@
 440	common	process_madvise		sys_process_madvise
 441	common	epoll_pwait2		sys_epoll_pwait2
 442	common	mount_setattr		sys_mount_setattr
+443	common	msgrcv_timed		sys_msgrcv_timed
+444	common	msgsnd_timed		sys_msgsnd_timed
 
 #
 # Due to a historical design error, certain syscalls are numbered differently
diff --git a/arch/xtensa/kernel/syscalls/syscall.tbl b/arch/xtensa/kernel/syscalls/syscall.tbl
index 365a9b8..12bdd62 100644
--- a/arch/xtensa/kernel/syscalls/syscall.tbl
+++ b/arch/xtensa/kernel/syscalls/syscall.tbl
@@ -413,3 +413,5 @@
 440	common	process_madvise			sys_process_madvise
 441	common	epoll_pwait2			sys_epoll_pwait2
 442	common	mount_setattr			sys_mount_setattr
+443	common	msgrcv_timed			sys_msgrcv_timed
+444	common	msgsnd_timed			sys_msgsnd_timed
diff --git a/include/linux/compat.h b/include/linux/compat.h
index 6e65be7..e2fd2ac 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -743,6 +743,10 @@ asmlinkage long compat_sys_msgrcv(int msqid, compat_uptr_t msgp,
 		compat_ssize_t msgsz, compat_long_t msgtyp, int msgflg);
 asmlinkage long compat_sys_msgsnd(int msqid, compat_uptr_t msgp,
 		compat_ssize_t msgsz, int msgflg);
+asmlinkage long compat_sys_msgrcv_timed(int msqid, compat_uptr_t msgp,
+		compat_ssize_t msgsz, compat_long_t msgtyp, int msgflg, compat_long_t timeoutms);
+asmlinkage long compat_sys_msgsnd_timed(int msqid, compat_uptr_t msgp,
+		compat_ssize_t msgsz, int msgflg, compat_long_t timeoutms);
 
 /* ipc/sem.c */
 asmlinkage long compat_sys_semctl(int semid, int semnum, int cmd, int arg);
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index 2839dc9..369cc19 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -808,6 +808,10 @@ asmlinkage long sys_msgrcv(int msqid, struct msgbuf __user *msgp,
 				size_t msgsz, long msgtyp, int msgflg);
 asmlinkage long sys_msgsnd(int msqid, struct msgbuf __user *msgp,
 				size_t msgsz, int msgflg);
+asmlinkage long sys_msgrcv_timed(int msqid, struct msgbuf __user *msgp,
+				size_t msgsz, long msgtyp, int msgflg, long timeoutms);
+asmlinkage long sys_msgsnd_timed(int msqid, struct msgbuf __user *msgp,
+				size_t msgsz, int msgflg, long timeoutms);
 
 /* ipc/sem.c */
 asmlinkage long sys_semget(key_t key, int nsems, int semflg);
diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h
index ce58cff..ef3cfad 100644
--- a/include/uapi/asm-generic/unistd.h
+++ b/include/uapi/asm-generic/unistd.h
@@ -561,6 +561,10 @@ __SC_COMP(__NR_msgctl, sys_msgctl, compat_sys_msgctl)
 __SC_COMP(__NR_msgrcv, sys_msgrcv, compat_sys_msgrcv)
 #define __NR_msgsnd 189
 __SC_COMP(__NR_msgsnd, sys_msgsnd, compat_sys_msgsnd)
+#define __NR_msgrcv_timed 443
+__SC_COMP(__NR_msgrcv_timed, sys_msgrcv_timed, compat_sys_msgrcv_timed)
+#define __NR_msgsnd_timed 444
+__SC_COMP(__NR_msgsnd_timed, sys_msgsnd_timed, compat_sys_msgsnd_timed)
 
 /* ipc/sem.c */
 #define __NR_semget 190
@@ -865,7 +869,7 @@ __SC_COMP(__NR_epoll_pwait2, sys_epoll_pwait2, compat_sys_epoll_pwait2)
 __SYSCALL(__NR_mount_setattr, sys_mount_setattr)
 
 #undef __NR_syscalls
-#define __NR_syscalls 443
+#define __NR_syscalls 445
 
 /*
  * 32 bit systems traditionally used different
diff --git a/ipc/msg.c b/ipc/msg.c
index acd1bc7..88167c0 100644
--- a/ipc/msg.c
+++ b/ipc/msg.c
@@ -838,13 +838,14 @@ static inline int pipelined_send(struct msg_queue *msq, struct msg_msg *msg,
 }
 
 static long do_msgsnd(int msqid, long mtype, void __user *mtext,
-		size_t msgsz, int msgflg)
+		size_t msgsz, int msgflg, long timeoutms)
 {
 	struct msg_queue *msq;
 	struct msg_msg *msg;
 	int err;
 	struct ipc_namespace *ns;
 	DEFINE_WAKE_Q(wake_q);
+	bool timeoutflag = false;
 
 	ns = current->nsproxy->ipc_ns;
 
@@ -905,7 +906,15 @@ static long do_msgsnd(int msqid, long mtype, void __user *mtext,
 
 		ipc_unlock_object(&msq->q_perm);
 		rcu_read_unlock();
-		schedule();
+
+		/* sometimes, we need msgsnd syscall return after a given time */
+		if (timeoutms <= 0) {
+			schedule();
+		} else {
+			timeoutms = schedule_timeout(timeoutms);
+			if (timeoutms == 0)
+				timeoutflag = true;
+		}
 
 		rcu_read_lock();
 		ipc_lock_object(&msq->q_perm);
@@ -918,6 +927,11 @@ static long do_msgsnd(int msqid, long mtype, void __user *mtext,
 		}
 		ss_del(&s);
 
+		if (true == timeoutflag) {
+			err = -ETIME;
+			goto out_unlock0;
+		}
+
 		if (signal_pending(current)) {
 			err = -ERESTARTNOHAND;
 			goto out_unlock0;
@@ -957,7 +971,7 @@ long ksys_msgsnd(int msqid, struct msgbuf __user *msgp, size_t msgsz,
 
 	if (get_user(mtype, &msgp->mtype))
 		return -EFAULT;
-	return do_msgsnd(msqid, mtype, msgp->mtext, msgsz, msgflg);
+	return do_msgsnd(msqid, mtype, msgp->mtext, msgsz, msgflg, 0);
 }
 
 SYSCALL_DEFINE4(msgsnd, int, msqid, struct msgbuf __user *, msgp, size_t, msgsz,
@@ -966,6 +980,18 @@ SYSCALL_DEFINE4(msgsnd, int, msqid, struct msgbuf __user *, msgp, size_t, msgsz,
 	return ksys_msgsnd(msqid, msgp, msgsz, msgflg);
 }
 
+SYSCALL_DEFINE5(msgsnd_timed, int, msqid, struct msgbuf __user *, msgp, size_t, msgsz,
+		int, msgflg, long, timeoutms)
+{
+	long mtype;
+
+	timeoutms = (timeoutms + 9) / 10;
+
+	if (get_user(mtype, &msgp->mtype))
+		return -EFAULT;
+	return do_msgsnd(msqid, mtype, msgp->mtext, msgsz, msgflg, timeoutms);
+}
+
 #ifdef CONFIG_COMPAT
 
 struct compat_msgbuf {
@@ -981,7 +1007,7 @@ long compat_ksys_msgsnd(int msqid, compat_uptr_t msgp,
 
 	if (get_user(mtype, &up->mtype))
 		return -EFAULT;
-	return do_msgsnd(msqid, mtype, up->mtext, (ssize_t)msgsz, msgflg);
+	return do_msgsnd(msqid, mtype, up->mtext, (ssize_t)msgsz, msgflg, 0);
 }
 
 COMPAT_SYSCALL_DEFINE4(msgsnd, int, msqid, compat_uptr_t, msgp,
@@ -989,6 +1015,20 @@ COMPAT_SYSCALL_DEFINE4(msgsnd, int, msqid, compat_uptr_t, msgp,
 {
 	return compat_ksys_msgsnd(msqid, msgp, msgsz, msgflg);
 }
+
+COMPAT_SYSCALL_DEFINE5(msgsnd_timed, int, msqid, compat_uptr_t, msgp,
+		       compat_ssize_t, msgsz, int, msgflg, compat_long_t, timeoutms)
+{
+	struct compat_msgbuf __user *up = compat_ptr(msgp);
+	compat_long_t mtype;
+
+	timeoutms = (timeoutms + 9) / 10;
+
+	if (get_user(mtype, &up->mtype))
+		return -EFAULT;
+
+	return do_msgsnd(msqid, mtype, up->mtext, (ssize_t)msgsz, msgflg, (long)timeoutms);
+}
 #endif
 
 static inline int convert_mode(long *msgtyp, int msgflg)
@@ -1088,13 +1128,14 @@ static struct msg_msg *find_msg(struct msg_queue *msq, long *msgtyp, int mode)
 }
 
 static long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp, int msgflg,
-	       long (*msg_handler)(void __user *, struct msg_msg *, size_t))
+	       long (*msg_handler)(void __user *, struct msg_msg *, size_t), long timeoutms)
 {
 	int mode;
 	struct msg_queue *msq;
 	struct ipc_namespace *ns;
 	struct msg_msg *msg, *copy = NULL;
 	DEFINE_WAKE_Q(wake_q);
+	bool timeoutflag = false;
 
 	ns = current->nsproxy->ipc_ns;
 
@@ -1187,7 +1228,15 @@ static long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp, in
 
 		ipc_unlock_object(&msq->q_perm);
 		rcu_read_unlock();
-		schedule();
+
+		/* sometimes, we need msgrcv syscall return after a given time */
+		if (timeoutms <= 0) {
+			schedule();
+		} else {
+			timeoutms = schedule_timeout(timeoutms);
+			if (timeoutms == 0)
+				timeoutflag = true;
+		}
 
 		/*
 		 * Lockless receive, part 1:
@@ -1229,6 +1278,12 @@ static long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp, in
 			goto out_unlock0;
 
 		list_del(&msr_d.r_list);
+
+		if (true == timeoutflag) {
+			msg = ERR_PTR(-ETIME);
+			goto out_unlock0;
+		}
+
 		if (signal_pending(current)) {
 			msg = ERR_PTR(-ERESTARTNOHAND);
 			goto out_unlock0;
@@ -1256,7 +1311,7 @@ static long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp, in
 long ksys_msgrcv(int msqid, struct msgbuf __user *msgp, size_t msgsz,
 		 long msgtyp, int msgflg)
 {
-	return do_msgrcv(msqid, msgp, msgsz, msgtyp, msgflg, do_msg_fill);
+	return do_msgrcv(msqid, msgp, msgsz, msgtyp, msgflg, do_msg_fill, 0);
 }
 
 SYSCALL_DEFINE5(msgrcv, int, msqid, struct msgbuf __user *, msgp, size_t, msgsz,
@@ -1265,6 +1320,13 @@ SYSCALL_DEFINE5(msgrcv, int, msqid, struct msgbuf __user *, msgp, size_t, msgsz,
 	return ksys_msgrcv(msqid, msgp, msgsz, msgtyp, msgflg);
 }
 
+SYSCALL_DEFINE6(msgrcv_timed, int, msqid, struct msgbuf __user *, msgp, size_t, msgsz,
+		long, msgtyp, int, msgflg, long, timeoutms)
+{
+	timeoutms = (timeoutms + 9) / 10;
+	return do_msgrcv(msqid, msgp, msgsz, msgtyp, msgflg, do_msg_fill, timeoutms);
+}
+
 #ifdef CONFIG_COMPAT
 static long compat_do_msg_fill(void __user *dest, struct msg_msg *msg, size_t bufsz)
 {
@@ -1284,7 +1346,7 @@ long compat_ksys_msgrcv(int msqid, compat_uptr_t msgp, compat_ssize_t msgsz,
 			compat_long_t msgtyp, int msgflg)
 {
 	return do_msgrcv(msqid, compat_ptr(msgp), (ssize_t)msgsz, (long)msgtyp,
-			 msgflg, compat_do_msg_fill);
+			 msgflg, compat_do_msg_fill, 0);
 }
 
 COMPAT_SYSCALL_DEFINE5(msgrcv, int, msqid, compat_uptr_t, msgp,
@@ -1293,6 +1355,15 @@ COMPAT_SYSCALL_DEFINE5(msgrcv, int, msqid, compat_uptr_t, msgp,
 {
 	return compat_ksys_msgrcv(msqid, msgp, msgsz, msgtyp, msgflg);
 }
+
+COMPAT_SYSCALL_DEFINE6(msgrcv_timed, int, msqid, compat_uptr_t, msgp,
+		       compat_ssize_t, msgsz, compat_long_t, msgtyp,
+		       int, msgflg, compat_long_t, timeoutms)
+{
+	timeoutms = (timeoutms + 9) / 10;
+	return do_msgrcv(msqid, compat_ptr(msgp), (ssize_t)msgsz, (long)msgtyp,
+		 msgflg, compat_do_msg_fill, (long)timeoutms);
+}
 #endif
 
 void msg_init_ns(struct ipc_namespace *ns)
diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c
index 19aa8068..783a1de 100644
--- a/kernel/sys_ni.c
+++ b/kernel/sys_ni.c
@@ -212,6 +212,10 @@ COND_SYSCALL(msgrcv);
 COND_SYSCALL_COMPAT(msgrcv);
 COND_SYSCALL(msgsnd);
 COND_SYSCALL_COMPAT(msgsnd);
+COND_SYSCALL(msgrcv_timed);
+COND_SYSCALL_COMPAT(msgrcv_timed);
+COND_SYSCALL(msgsnd_timed);
+COND_SYSCALL_COMPAT(msgsnd_timed);
 
 /* ipc/sem.c */
 COND_SYSCALL(semget);
-- 
2.7.4


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2021-02-28 19:51 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <tencent_2CB9BD7D4063DE3F6845F79176B2D29A7E09@qq.com>
2021-02-28 15:38 ` [PATCH] ipc/msg: add msgsnd_timed and msgrcv_timed syscall for system V message queue Arnd Bergmann
     [not found]   ` <tencent_2B7E37BD494059DF7D6845F641769CD28209@qq.com>
2021-02-28 19:49     ` Arnd Bergmann
2021-02-27  6:52 Eric Gao
2021-02-27 12:29 ` Arnd Bergmann

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).