From patchwork Thu Dec 3 20:40:48 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Paul E. Murphy" X-Patchwork-Id: 9872 Received: (qmail 50647 invoked by alias); 3 Dec 2015 20:40:56 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 50635 invoked by uid 89); 3 Dec 2015 20:40:55 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.9 required=5.0 tests=AWL, BAYES_00, KAM_LAZY_DOMAIN_SECURITY, T_RP_MATCHES_RCVD autolearn=no version=3.3.2 X-HELO: e39.co.us.ibm.com X-IBM-Helo: d01dlp02.pok.ibm.com X-IBM-MailFrom: murphyp@linux.vnet.ibm.com X-IBM-RcptTo: libc-alpha@sourceware.org From: "Paul E. Murphy" Subject: [PATCH] powerpc: Enable demuxed sysv IPC syscalls To: "libc-alpha@sourceware.org" , Tulio Magno Quites Machado Filho Message-ID: <5660A8D0.5090003@linux.vnet.ibm.com> Date: Thu, 3 Dec 2015 14:40:48 -0600 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 X-TM-AS-MML: disable X-Content-Scanned: Fidelis XPS MAILER x-cbid: 15120320-0033-0000-0000-0000071A102D PPC kernel 4.4rc1 and newer support these syscalls. They should be a little faster. This adds support for the common implementations. Other architectures need only define the appropriate macros in their kernel-features.h, if they can take advantage of them. 2015-12-03 Paul E. Murphy * sysdeps/unix/sysv/linux/msgctl.c (__old_msgctl): Add support for direct syscall. (__new_msgctl): Likewise. * sysdeps/unix/sysv/linux/msgget.c (msgget): Likewise. * sysdeps/unix/sysv/linux/msgrcv.c (__libc_msgrcv): Likewise. * sysdeps/unix/sysv/linux/msgsnd.c (__libc_msgsnd): Likewise. * sysdeps/unix/sysv/linux/semctl.c (__old_semctl): Likewise. (__new_semctl): Likewise. * sysdeps/unix/sysv/linux/semget.c (semget): Likewise. * sysdeps/unix/sysv/linux/semop.c (semop): Likewise. * sysdeps/unix/sysv/linux/semtimedop.c (semtimedop): Likewise. * sysdeps/unix/sysv/linux/shmctl.c (__old_shmctl): Likewise. (__new_shmctl): Likewise. * sysdeps/unix/sysv/linux/shmdt.c (shmdt): Likewise. * sysdeps/unix/sysv/linux/shmget.c (shmget): Likewise. * sysdeps/unix/sysc/linux/powerpc/kernel-features.h: (__ASSUME_SEMOP_SYSCALL): Define for kernel 4.4 and newer. (__ASSUME_SEMGET_SYSCALL): Likewise. (__ASSUME_SEMCTL_SYSCALL): Likewise. (__ASSUME_SEMTIMEDOP_SYSCALL): Likewise. (__ASSUME_MSGSND_SYSCALL): Likewise. (__ASSUME_MSGRCV_SYSCALL): Likewise. (__ASSUME_MSGGET_SYSCALL): Likewise. (__ASSUME_MSGCTL_SYSCALL): Likewise. (__ASSUME_SHMAT_SYSCALL): Likewise. (__ASSUME_SHMDT_SYSCALL): Likewise. (__ASSUME_SHMGET_SYSCALL): Likewise. (__ASSUME_SHMCTL_SYSCALL): Likewise. --- sysdeps/unix/sysv/linux/msgctl.c | 9 +++++++++ sysdeps/unix/sysv/linux/msgget.c | 4 ++++ sysdeps/unix/sysv/linux/msgrcv.c | 4 ++++ sysdeps/unix/sysv/linux/msgsnd.c | 4 ++++ sysdeps/unix/sysv/linux/powerpc/kernel-features.h | 16 ++++++++++++++++ sysdeps/unix/sysv/linux/semctl.c | 8 ++++++++ sysdeps/unix/sysv/linux/semget.c | 4 ++++ sysdeps/unix/sysv/linux/semop.c | 4 ++++ sysdeps/unix/sysv/linux/semtimedop.c | 4 ++++ sysdeps/unix/sysv/linux/shmat.c | 8 +++++++- sysdeps/unix/sysv/linux/shmctl.c | 8 ++++++++ sysdeps/unix/sysv/linux/shmdt.c | 4 ++++ sysdeps/unix/sysv/linux/shmget.c | 4 ++++ 13 files changed, 80 insertions(+), 1 deletion(-) diff --git a/sysdeps/unix/sysv/linux/msgctl.c b/sysdeps/unix/sysv/linux/msgctl.c index a24dc38..86f34a2 100644 --- a/sysdeps/unix/sysv/linux/msgctl.c +++ b/sysdeps/unix/sysv/linux/msgctl.c @@ -56,7 +56,11 @@ int attribute_compat_text_section __old_msgctl (int msqid, int cmd, struct __old_msqid_ds *buf) { +#ifdef __ASSUME_MSGCTL_SYSCALL + return INLINE_SYSCALL (msgctl, 3, msqid, cmd, buf); +#else return INLINE_SYSCALL (ipc, 5, IPCOP_msgctl, msqid, cmd, 0, buf); +#endif } compat_symbol (libc, __old_msgctl, msgctl, GLIBC_2_0); #endif @@ -64,7 +68,12 @@ compat_symbol (libc, __old_msgctl, msgctl, GLIBC_2_0); int __new_msgctl (int msqid, int cmd, struct msqid_ds *buf) { +#ifdef __ASSUME_MSGCTL_SYSCALL + return INLINE_SYSCALL (msgctl, 3, msqid, cmd | __IPC_64, buf); +#else return INLINE_SYSCALL (ipc, 5, IPCOP_msgctl, msqid, cmd | __IPC_64, 0, buf); +#endif + } versioned_symbol (libc, __new_msgctl, msgctl, GLIBC_2_2); diff --git a/sysdeps/unix/sysv/linux/msgget.c b/sysdeps/unix/sysv/linux/msgget.c index a206b84..b57497e 100644 --- a/sysdeps/unix/sysv/linux/msgget.c +++ b/sysdeps/unix/sysv/linux/msgget.c @@ -30,5 +30,9 @@ int msgget (key_t key, int msgflg) { +#ifdef __ASSUME_MSGGET_SYSCALL + return INLINE_SYSCALL (msgget, 2, key, msgflg); +#else return INLINE_SYSCALL (ipc, 5, IPCOP_msgget, key, msgflg, 0, NULL); +#endif } diff --git a/sysdeps/unix/sysv/linux/msgrcv.c b/sysdeps/unix/sysv/linux/msgrcv.c index 660ff29..eb36178 100644 --- a/sysdeps/unix/sysv/linux/msgrcv.c +++ b/sysdeps/unix/sysv/linux/msgrcv.c @@ -36,6 +36,9 @@ ssize_t __libc_msgrcv (int msqid, void *msgp, size_t msgsz, long int msgtyp, int msgflg) { +#ifdef __ASSUME_MSGRCV_SYSCALL + return SYSCALL_CANCEL (msgrcv, msqid, msgp, msgsz, msgtyp, msgflg); +#else /* The problem here is that Linux' calling convention only allows up to fives parameters to a system call. */ struct ipc_kludge tmp; @@ -44,5 +47,6 @@ __libc_msgrcv (int msqid, void *msgp, size_t msgsz, long int msgtyp, tmp.msgtyp = msgtyp; return SYSCALL_CANCEL (ipc, IPCOP_msgrcv, msqid, msgsz, msgflg, &tmp); +#endif } weak_alias (__libc_msgrcv, msgrcv) diff --git a/sysdeps/unix/sysv/linux/msgsnd.c b/sysdeps/unix/sysv/linux/msgsnd.c index dfed539..176027c 100644 --- a/sysdeps/unix/sysv/linux/msgsnd.c +++ b/sysdeps/unix/sysv/linux/msgsnd.c @@ -26,7 +26,11 @@ int __libc_msgsnd (int msqid, const void *msgp, size_t msgsz, int msgflg) { +#ifdef __ASSUME_MSGSND_SYSCALL + return SYSCALL_CANCEL (msgsnd, msqid, (void*) msgp, msgsz, msgflg); +#else return SYSCALL_CANCEL (ipc, IPCOP_msgsnd, msqid, msgsz, msgflg, (void *) msgp); +#endif } weak_alias (__libc_msgsnd, msgsnd) diff --git a/sysdeps/unix/sysv/linux/powerpc/kernel-features.h b/sysdeps/unix/sysv/linux/powerpc/kernel-features.h index 8a536cf..213c3a7 100644 --- a/sysdeps/unix/sysv/linux/powerpc/kernel-features.h +++ b/sysdeps/unix/sysv/linux/powerpc/kernel-features.h @@ -57,4 +57,20 @@ #endif #define __ASSUME_SENDMMSG_SYSCALL_WITH_SOCKETCALL 1 +/* Demuxed sysv IPC syscalls added in 4.4. */ +#if __LINUX_KERNEL_VERSION >= 0x040400 +# define __ASSUME_SEMOP_SYSCALL 1 +# define __ASSUME_SEMGET_SYSCALL 1 +# define __ASSUME_SEMCTL_SYSCALL 1 +# define __ASSUME_SEMTIMEDOP_SYSCALL 1 +# define __ASSUME_MSGSND_SYSCALL 1 +# define __ASSUME_MSGRCV_SYSCALL 1 +# define __ASSUME_MSGGET_SYSCALL 1 +# define __ASSUME_MSGCTL_SYSCALL 1 +# define __ASSUME_SHMAT_SYSCALL 1 +# define __ASSUME_SHMDT_SYSCALL 1 +# define __ASSUME_SHMGET_SYSCALL 1 +# define __ASSUME_SHMCTL_SYSCALL 1 +#endif + #include_next diff --git a/sysdeps/unix/sysv/linux/semctl.c b/sysdeps/unix/sysv/linux/semctl.c index 81a33a9..7d8533e 100644 --- a/sysdeps/unix/sysv/linux/semctl.c +++ b/sysdeps/unix/sysv/linux/semctl.c @@ -83,8 +83,12 @@ __old_semctl (int semid, int semnum, int cmd, ...) break; } +#ifdef __ASSUME_SEMCTL_SYSCALL + return INLINE_SYSCALL (semctl, 4, semid, semnum, cmd, &arg); +#else return INLINE_SYSCALL (ipc, 5, IPCOP_semctl, semid, semnum, cmd, &arg); +#endif } compat_symbol (libc, __old_semctl, semctl, GLIBC_2_0); #endif @@ -113,8 +117,12 @@ __new_semctl (int semid, int semnum, int cmd, ...) break; } +#ifdef __ASSUME_SEMCTL_SYSCALL + return INLINE_SYSCALL (semctl, 4, semid, semnum, cmd | __IPC_64, &arg); +#else return INLINE_SYSCALL (ipc, 5, IPCOP_semctl, semid, semnum, cmd | __IPC_64, &arg); +#endif } versioned_symbol (libc, __new_semctl, semctl, GLIBC_2_2); diff --git a/sysdeps/unix/sysv/linux/semget.c b/sysdeps/unix/sysv/linux/semget.c index 29ca0ae..48948ff 100644 --- a/sysdeps/unix/sysv/linux/semget.c +++ b/sysdeps/unix/sysv/linux/semget.c @@ -30,5 +30,9 @@ int semget (key_t key, int nsems, int semflg) { +#ifdef __ASSUME_SEMGET_SYSCALL + return INLINE_SYSCALL (semget, 3, key, nsems, semflg); +#else return INLINE_SYSCALL (ipc, 5, IPCOP_semget, key, nsems, semflg, NULL); +#endif } diff --git a/sysdeps/unix/sysv/linux/semop.c b/sysdeps/unix/sysv/linux/semop.c index 18a2928..165ce69 100644 --- a/sysdeps/unix/sysv/linux/semop.c +++ b/sysdeps/unix/sysv/linux/semop.c @@ -28,5 +28,9 @@ int semop (int semid, struct sembuf *sops, size_t nsops) { +#ifdef __ASSUME_SEMOP_SYSCALL + return INLINE_SYSCALL (semop, 3, semid, sops, (int) nsops); +#else return INLINE_SYSCALL (ipc, 5, IPCOP_semop, semid, (int) nsops, 0, sops); +#endif } diff --git a/sysdeps/unix/sysv/linux/semtimedop.c b/sysdeps/unix/sysv/linux/semtimedop.c index 7a80b48..13afa7d 100644 --- a/sysdeps/unix/sysv/linux/semtimedop.c +++ b/sysdeps/unix/sysv/linux/semtimedop.c @@ -29,7 +29,11 @@ int semtimedop (int semid, struct sembuf *sops, size_t nsops, const struct timespec *timeout) { +#ifdef __ASSUME_SEMTIMEDOP_SYSCALL + return INLINE_SYSCALL (semtimedop, 4, semid, sops, (int) nsops, timeout); +#else return INLINE_SYSCALL (ipc, 6, IPCOP_semtimedop, semid, (int) nsops, 0, sops, timeout); +#endif } diff --git a/sysdeps/unix/sysv/linux/shmat.c b/sysdeps/unix/sysv/linux/shmat.c index b75bb9e..f2fc5b1 100644 --- a/sysdeps/unix/sysv/linux/shmat.c +++ b/sysdeps/unix/sysv/linux/shmat.c @@ -33,12 +33,18 @@ shmat (int shmid, const void *shmaddr, int shmflg) { INTERNAL_SYSCALL_DECL(err); unsigned long resultvar; - void *raddr; + void *raddr __attribute__ ((unused)); +#ifdef __ASSUME_SHMAT_SYSCALL + resultvar = INTERNAL_SYSCALL (shmat, err, 3, shmid, (void *) shmaddr, + shmflg); + +#else resultvar = INTERNAL_SYSCALL (ipc, err, 5, IPCOP_shmat, shmid, shmflg, (long int) &raddr, (void *) shmaddr); +#endif if (INTERNAL_SYSCALL_ERROR_P (resultvar, err)) return (void *) INLINE_SYSCALL_ERROR_RETURN_VALUE (INTERNAL_SYSCALL_ERRNO (resultvar, err)); diff --git a/sysdeps/unix/sysv/linux/shmctl.c b/sysdeps/unix/sysv/linux/shmctl.c index 55cd4b3..04c19ca 100644 --- a/sysdeps/unix/sysv/linux/shmctl.c +++ b/sysdeps/unix/sysv/linux/shmctl.c @@ -63,7 +63,11 @@ int attribute_compat_text_section __old_shmctl (int shmid, int cmd, struct __old_shmid_ds *buf) { +#ifdef __ASSUME_SHMCTL_SYSCALL + return INLINE_SYSCALL (shmctl, 3, shmid, cmd, buf); +#else return INLINE_SYSCALL (ipc, 5, IPCOP_shmctl, shmid, cmd, 0, buf); +#endif } compat_symbol (libc, __old_shmctl, shmctl, GLIBC_2_0); #endif @@ -71,8 +75,12 @@ compat_symbol (libc, __old_shmctl, shmctl, GLIBC_2_0); int __new_shmctl (int shmid, int cmd, struct shmid_ds *buf) { +#ifdef __ASSUME_SHMCTL_SYSCALL + return INLINE_SYSCALL (shmctl, 3, shmid, cmd | __IPC_64, buf); +#else return INLINE_SYSCALL (ipc, 5, IPCOP_shmctl, shmid, cmd | __IPC_64, 0, buf); +#endif } versioned_symbol (libc, __new_shmctl, shmctl, GLIBC_2_2); diff --git a/sysdeps/unix/sysv/linux/shmdt.c b/sysdeps/unix/sysv/linux/shmdt.c index e7f4196..40a2ba5 100644 --- a/sysdeps/unix/sysv/linux/shmdt.c +++ b/sysdeps/unix/sysv/linux/shmdt.c @@ -29,5 +29,9 @@ int shmdt (const void *shmaddr) { +#ifdef __ASSUME_SHMDT_SYSCALL + return INLINE_SYSCALL (shmdt, 1, (void *) shmaddr); +#else return INLINE_SYSCALL (ipc, 5, IPCOP_shmdt, 0, 0, 0, (void *) shmaddr); +#endif } diff --git a/sysdeps/unix/sysv/linux/shmget.c b/sysdeps/unix/sysv/linux/shmget.c index 0cc2650..5f0a662 100644 --- a/sysdeps/unix/sysv/linux/shmget.c +++ b/sysdeps/unix/sysv/linux/shmget.c @@ -30,5 +30,9 @@ int shmget (key_t key, size_t size, int shmflg) { +#ifdef __ASSUME_SHMGET_SYSCALL + return INLINE_SYSCALL (shmget, 3, key, size, shmflg); +#else return INLINE_SYSCALL (ipc, 5, IPCOP_shmget, key, size, shmflg, NULL); +#endif }