diff --git a/ChangeLog b/ChangeLog
index 9ca390a9c3..fb54a4aa61 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1029,6 +1029,9 @@
 	* sysdeps/unix/sysv/linux/nanosleep.c: Likewise.
 	* sysdeps/unix/sysv/linux/nanosleep_nocancel.c: Likewise.
 	* sysdeps/unix/sysv/linux/gettimeofday.c: Use clock_gettime64 syscall for gettimeofday.
+	* sysdeps/unix/sysv/linux/wait.c: Use __NR_waitid if avaliable.
+	* sysdeps/unix/sysv/linux/waitpid.c: Likewise.
+	* sysdeps/unix/sysv/linux/waitpid_nocancel.c: Likewise.
 
 2019-06-20  Dmitry V. Levin  <ldv@altlinux.org>
 	    Florian Weimer  <fweimer@redhat.com>
diff --git a/sysdeps/unix/sysv/linux/wait.c b/sysdeps/unix/sysv/linux/wait.c
index 498bd1c095..e727afa14b 100644
--- a/sysdeps/unix/sysv/linux/wait.c
+++ b/sysdeps/unix/sysv/linux/wait.c
@@ -26,9 +26,42 @@
 pid_t
 __libc_wait (int *stat_loc)
 {
-  pid_t result = SYSCALL_CANCEL (wait4, WAIT_ANY, stat_loc, 0,
-				 (struct rusage *) NULL);
-  return result;
+#ifdef __NR_waitid
+  siginfo_t infop;
+  __pid_t ret;
+
+  ret = SYSCALL_CANCEL (waitid, P_ALL, 0, &infop, WEXITED, NULL);
+
+  if (ret < 0) {
+    return ret;
+  }
+
+  if (stat_loc) {
+    *stat_loc = 0;
+    switch (infop.si_code) {
+    case CLD_EXITED:
+      *stat_loc = infop.si_status << 8;
+      break;
+    case CLD_DUMPED:
+      *stat_loc = 0x80;
+    case CLD_KILLED:
+      *stat_loc |= infop.si_status;
+      break;
+    case CLD_TRAPPED:
+    case CLD_STOPPED:
+      *stat_loc = infop.si_status << 8 | 0x7f;
+      break;
+    case CLD_CONTINUED:
+      *stat_loc = 0xffff;
+      break;
+    }
+  }
+
+  return infop.si_pid;
+#else
+  return SYSCALL_CANCEL (wait4, WAIT_ANY, stat_loc, 0,
+                         (struct rusage *) NULL);
+#endif
 }
 
 weak_alias (__libc_wait, __wait)
diff --git a/sysdeps/unix/sysv/linux/waitpid.c b/sysdeps/unix/sysv/linux/waitpid.c
index f0897574c0..7d4e0bb77d 100644
--- a/sysdeps/unix/sysv/linux/waitpid.c
+++ b/sysdeps/unix/sysv/linux/waitpid.c
@@ -20,12 +20,58 @@
 #include <sysdep-cancel.h>
 #include <stdlib.h>
 #include <sys/wait.h>
+#include <unistd.h>
 
 __pid_t
 __waitpid (__pid_t pid, int *stat_loc, int options)
 {
 #ifdef __NR_waitpid
   return SYSCALL_CANCEL (waitpid, pid, stat_loc, options);
+#elif defined(__NR_waitid)
+  __pid_t ret;
+  idtype_t idtype = P_PID;
+  siginfo_t infop;
+
+  if (pid < -1) {
+    idtype = P_PGID;
+    pid *= -1;
+  } else if (pid == -1) {
+    idtype = P_ALL;
+  } else if (pid == 0) {
+    idtype = P_PGID;
+    pid = getpgrp();
+  }
+
+  options |= WEXITED;
+
+  ret = SYSCALL_CANCEL (waitid, idtype, pid, &infop, options, NULL);
+
+  if (ret < 0) {
+    return ret;
+  }
+
+  if (stat_loc) {
+    *stat_loc = 0;
+    switch (infop.si_code) {
+    case CLD_EXITED:
+      *stat_loc = infop.si_status << 8;
+      break;
+    case CLD_DUMPED:
+      *stat_loc = 0x80;
+    case CLD_KILLED:
+      *stat_loc |= infop.si_status;
+      break;
+    case CLD_TRAPPED:
+    case CLD_STOPPED:
+      *stat_loc = infop.si_status << 8 | 0x7f;
+      break;
+    case CLD_CONTINUED:
+      *stat_loc = 0xffff;
+      break;
+    }
+  }
+
+  return infop.si_pid;
 #else
   return SYSCALL_CANCEL (wait4, pid, stat_loc, options, NULL);
 #endif
diff --git a/sysdeps/unix/sysv/linux/waitpid_nocancel.c b/sysdeps/unix/sysv/linux/waitpid_nocancel.c
index 89e36a5c0b..c92f05421b 100644
--- a/sysdeps/unix/sysv/linux/waitpid_nocancel.c
+++ b/sysdeps/unix/sysv/linux/waitpid_nocancel.c
@@ -27,6 +27,51 @@ __waitpid_nocancel (__pid_t pid, int *stat_loc, int options)
 {
 #ifdef __NR_waitpid
   return INLINE_SYSCALL_CALL (waitpid, pid, stat_loc, options);
+#elif defined(__NR_waitid)
+  __pid_t ret;
+  idtype_t idtype = P_PID;
+  siginfo_t infop;
+
+  if (pid < -1) {
+    idtype = P_PGID;
+    pid *= -1;
+  } else if (pid == -1) {
+    idtype = P_ALL;
+  } else if (pid == 0) {
+    idtype = P_PGID;
+    pid = getpgrp();
+  }
+
+  options |= WEXITED;
+
+  ret = INLINE_SYSCALL_CALL (waitid, idtype, pid, &infop, options, NULL);
+
+  if (ret < 0) {
+    return ret;
+  }
+
+  if (stat_loc) {
+    *stat_loc = 0;
+    switch (infop.si_code) {
+    case CLD_EXITED:
+      *stat_loc = infop.si_status << 8;
+      break;
+    case CLD_DUMPED:
+      *stat_loc = 0x80;
+    case CLD_KILLED:
+      *stat_loc |= infop.si_status;
+      break;
+    case CLD_TRAPPED:
+    case CLD_STOPPED:
+      *stat_loc = infop.si_status << 8 | 0x7f;
+      break;
+    case CLD_CONTINUED:
+      *stat_loc = 0xffff;
+      break;
+    }
+  }
+
+  return infop.si_pid;
 #else
   return INLINE_SYSCALL_CALL (wait4, pid, stat_loc, options, NULL);
 #endif
