This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[PATCH] powerpc: Enable demuxed sysv IPC syscalls
- From: "Paul E. Murphy" <murphyp at linux dot vnet dot ibm dot com>
- To: "libc-alpha at sourceware dot org" <libc-alpha at sourceware dot org>, Tulio Magno Quites Machado Filho <tuliom at linux dot vnet dot ibm dot com>
- Date: Thu, 3 Dec 2015 14:40:48 -0600
- Subject: [PATCH] powerpc: Enable demuxed sysv IPC syscalls
- Authentication-results: sourceware.org; auth=none
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 <murphyp@linux.vnet.ibm.com>
* 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 <kernel-features.h>
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
}
--
2.4.3