[7/7] nptl: ppc32: Fix Race conditions in pthread cancellation, (BZ#12683)

Message ID 5425C354.6080703@linux.vnet.ibm.com
State Superseded
Headers

Commit Message

Adhemerval Zanella Netto Sept. 26, 2014, 7:49 p.m. UTC
  This patches adds the ppc32 modification required for the BZ#12683
fix.  It basically removes the enable_asynccancel/disable_asynccancel
function usage on code used on ppc32.

Tested on powerpc32, powerpc64, and x86_64.

--

	* sysdeps/powerpc/nptl/pthreaddef.h (__pthread_get_ip): Add powerpc32
	support.
	* sysdeps/unix/sysv/linux/fallocate.c (fallocate): Remove calls to
	enable/disable asynchronous cancellation and use call cancellable
	syscall entrypoint when required.
	* sysdeps/unix/sysv/linux/fallocate64.c (fallocate64): Likewise.
	* sysdeps/unix/sysv/linux/i386/fcntl.c (__fcntl_nocancel): Likewise.
	(__libc_fcntl): Likewise.
	* sysdeps/unix/sysv/linux/open64.c (__libc_open64): Likewise.
	* sysdeps/unix/sysv/linux/powerpc/powerpc32/pread.c (__libc_pread):
	Likewise.
	* sysdeps/unix/sysv/linux/powerpc/powerpc32/pread64.c (__libc_read64):
	Likewise.
	* sysdeps/unix/sysv/linux/powerpc/powerpc32/pwrite.c (__libc_pwrite):
	Likewise.
	* sysdeps/unix/sysv/linux/powerpc/powerpc32/pwrite64.c
	(__libc_pwrite64): Likewise.
	* sysdeps/unix/sysv/linux/powerpc/powerpc32/socket.S (__socket):
	Likewise.
	* sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h (PSEUDO):
	Likewise.
	* sysdeps/unix/sysv/linux/preadv.c (PREADV): Likewise.
	* sysdeps/unix/sysv/linux/pwritev.c (PWRITEV): Likewise.
	* sysdeps/unix/sysv/linux/sync_file_range.c (sync_file_range):
	Likewise.
	* sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h
	[SYSCALL_CANCEL_ERROR]: New macro.
	[SYSCALL_CANCEL_ERRNO]: New macro.

---
  

Patch

diff --git a/sysdeps/powerpc/nptl/pthreaddef.h b/sysdeps/powerpc/nptl/pthreaddef.h
index 5fe1cdb..5402154 100644
--- a/sysdeps/powerpc/nptl/pthreaddef.h
+++ b/sysdeps/powerpc/nptl/pthreaddef.h
@@ -38,7 +38,11 @@ 
 static inline
 const char * __pthread_get_ip (const ucontext_t *uc)
 {
+# ifdef __powerpc64__
   return (char *)uc->uc_mcontext.gp_regs[PT_NIP];
+# else
+  return (char *)uc->uc_mcontext.uc_regs->gregs[PT_NIP];
+# endif
 }
 
 #endif
diff --git a/sysdeps/unix/sysv/linux/fallocate.c b/sysdeps/unix/sysv/linux/fallocate.c
index 206d3d9..6760239 100644
--- a/sysdeps/unix/sysv/linux/fallocate.c
+++ b/sysdeps/unix/sysv/linux/fallocate.c
@@ -25,21 +25,9 @@  int
 fallocate (int fd, int mode, __off_t offset, __off_t len)
 {
 #ifdef __NR_fallocate
-  if (SINGLE_THREAD_P)
-    return INLINE_SYSCALL (fallocate, 6, fd, mode,
-			   __LONG_LONG_PAIR (offset >> 31, offset),
-			   __LONG_LONG_PAIR (len >> 31, len));
-
-  int result;
-  int oldtype = LIBC_CANCEL_ASYNC ();
-
-  result = INLINE_SYSCALL (fallocate, 6, fd, mode,
-			   __LONG_LONG_PAIR (offset >> 31, offset),
-			   __LONG_LONG_PAIR (len >> 31, len));
-
-  LIBC_CANCEL_RESET (oldtype);
-
-  return result;
+  return SYSCALL_CANCEL (fallocate, fd, mode,
+			 __LONG_LONG_PAIR (offset >> 31, offset),
+			 __LONG_LONG_PAIR (len >> 31, len));
 #else
   __set_errno (ENOSYS);
   return -1;
diff --git a/sysdeps/unix/sysv/linux/fallocate64.c b/sysdeps/unix/sysv/linux/fallocate64.c
index e5380c7..5c32fee 100644
--- a/sysdeps/unix/sysv/linux/fallocate64.c
+++ b/sysdeps/unix/sysv/linux/fallocate64.c
@@ -25,25 +25,11 @@  int
 fallocate64 (int fd, int mode, __off64_t offset, __off64_t len)
 {
 #ifdef __NR_fallocate
-  if (SINGLE_THREAD_P)
-    return INLINE_SYSCALL (fallocate, 6, fd, mode,
-			   __LONG_LONG_PAIR ((long int) (offset >> 32),
-					     (long int) offset),
-			   __LONG_LONG_PAIR ((long int) (len >> 32),
-					     (long int) len));
-
-  int result;
-  int oldtype = LIBC_CANCEL_ASYNC ();
-
-  result = INLINE_SYSCALL (fallocate, 6, fd, mode,
-			   __LONG_LONG_PAIR ((long int) (offset >> 32),
-					     (long int) offset),
-			   __LONG_LONG_PAIR ((long int) (len >> 32),
-					     (long int) len));
-
-  LIBC_CANCEL_RESET (oldtype);
-
-  return result;
+  return SYSCALL_CANCEL (fallocate, fd, mode,
+			 __LONG_LONG_PAIR ((long int) (offset >> 32),
+					   (long int) offset),
+			 __LONG_LONG_PAIR ((long int) (len >> 32),
+					   (long int) len));
 #else
   __set_errno (ENOSYS);
   return -1;
diff --git a/sysdeps/unix/sysv/linux/i386/fcntl.c b/sysdeps/unix/sysv/linux/i386/fcntl.c
index c76878c..038fa8c 100644
--- a/sysdeps/unix/sysv/linux/i386/fcntl.c
+++ b/sysdeps/unix/sysv/linux/i386/fcntl.c
@@ -23,7 +23,7 @@ 
 
 #include <sys/syscall.h>
 
-#ifndef NO_CANCELLATION
+#ifndef IS_IN_rtld
 int
 __fcntl_nocancel (int fd, int cmd, ...)
 {
@@ -36,8 +36,7 @@  __fcntl_nocancel (int fd, int cmd, ...)
 
   return INLINE_SYSCALL (fcntl64, 3, fd, cmd, arg);
 }
-#endif /* NO_CANCELLATION */
-
+#endif
 
 int
 __libc_fcntl (int fd, int cmd, ...)
@@ -49,16 +48,10 @@  __libc_fcntl (int fd, int cmd, ...)
   arg = va_arg (ap, void *);
   va_end (ap);
 
-  if (SINGLE_THREAD_P || (cmd != F_SETLKW && cmd != F_SETLKW64))
+  if ((cmd != F_SETLKW) && (cmd != F_SETLKW64))
     return INLINE_SYSCALL (fcntl64, 3, fd, cmd, arg);
 
-  int oldtype = LIBC_CANCEL_ASYNC ();
-
-  int result = INLINE_SYSCALL (fcntl64, 3, fd, cmd, arg);
-
-  LIBC_CANCEL_RESET (oldtype);
-
-  return result;
+  return SYSCALL_CANCEL (fcntl64, fd, cmd, arg);
 }
 libc_hidden_def (__libc_fcntl)
 
diff --git a/sysdeps/unix/sysv/linux/open64.c b/sysdeps/unix/sysv/linux/open64.c
index 0d63806..268eb87 100644
--- a/sysdeps/unix/sysv/linux/open64.c
+++ b/sysdeps/unix/sysv/linux/open64.c
@@ -36,16 +36,7 @@  __libc_open64 (const char *file, int oflag, ...)
       va_end (arg);
     }
 
-  if (SINGLE_THREAD_P)
-    return INLINE_SYSCALL (open, 3, file, oflag | O_LARGEFILE, mode);
-
-  int oldtype = LIBC_CANCEL_ASYNC ();
-
-  int result = INLINE_SYSCALL (open, 3, file, oflag | O_LARGEFILE, mode);
-
-  LIBC_CANCEL_RESET (oldtype);
-
-  return result;
+  return SYSCALL_CANCEL (open, file, oflag | O_LARGEFILE, mode);
 }
 weak_alias (__libc_open64, __open64)
 libc_hidden_weak (__open64)
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/pread.c b/sysdeps/unix/sysv/linux/powerpc/powerpc32/pread.c
index 04903a5..faf7dfc 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/pread.c
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/pread.c
@@ -26,26 +26,8 @@ 
 ssize_t
 __libc_pread (int fd, void *buf, size_t count, off_t offset)
 {
-  ssize_t result;
-
-  if (SINGLE_THREAD_P)
-    {
-      /* On PPC32 64bit values are aligned in odd/even register pairs.  */
-      result = INLINE_SYSCALL (pread, 6, fd, buf, count,
-			       0, offset >> 31, offset);
-
-      return result;
-    }
-
-  int oldtype = LIBC_CANCEL_ASYNC ();
-
   /* On PPC32 64bit values are aligned in odd/even register pairs.  */
-  result = INLINE_SYSCALL (pread, 6, fd, buf, count,
-			       0, offset >> 31, offset);
-
-  LIBC_CANCEL_RESET (oldtype);
-
-  return result;
+  return SYSCALL_CANCEL (pread, fd, buf, count, 0, offset >> 31, offset);
 }
 
 strong_alias (__libc_pread, __pread)
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/pread64.c b/sysdeps/unix/sysv/linux/powerpc/powerpc32/pread64.c
index 88a0ec9..e7be2ed 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/pread64.c
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/pread64.c
@@ -26,28 +26,9 @@ 
 ssize_t
 __libc_pread64 (int fd, void *buf, size_t count, off64_t offset)
 {
-  ssize_t result;
-
-  if (SINGLE_THREAD_P)
-    {
-      /* On PPC32 64bit values are aligned in odd/even register pairs.  */
-      result = INLINE_SYSCALL (pread, 6, fd, buf, count,
-			       0, (long) (offset >> 32),
-			       (long) offset);
-
-      return result;
-    }
-
-  int oldtype = LIBC_CANCEL_ASYNC ();
-
   /* On PPC32 64bit values are aligned in odd/even register pairs.  */
-  result = INLINE_SYSCALL (pread, 6, fd, buf, count,
-			   0, (long) (offset >> 32),
-			   (long) offset);
-
-  LIBC_CANCEL_RESET (oldtype);
-
-  return result;
+  return SYSCALL_CANCEL (pread, fd, buf, count, 0, (long) (offset >> 32),
+			       (long) offset);
 }
 
 weak_alias (__libc_pread64, __pread64)
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/pwrite.c b/sysdeps/unix/sysv/linux/powerpc/powerpc32/pwrite.c
index 661ed41..75b01fc 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/pwrite.c
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/pwrite.c
@@ -27,26 +27,8 @@ 
 ssize_t
 __libc_pwrite (int fd, const void *buf, size_t count, off_t offset)
 {
-  ssize_t result;
-
-  if (SINGLE_THREAD_P)
-    {
-      /* On PPC32 64bit values are aligned in odd/even register pairs.  */
-      result = INLINE_SYSCALL (pwrite, 6, fd, buf, count,
-			       0, offset >> 31, offset);
-
-      return result;
-    }
-
-  int oldtype = LIBC_CANCEL_ASYNC ();
-
   /* On PPC32 64bit values are aligned in odd/even register pairs.  */
-  result = INLINE_SYSCALL (pwrite, 6, fd, buf, count,
-			   0, offset >> 31, offset);
-
-  LIBC_CANCEL_RESET (oldtype);
-
-  return result;
+  return SYSCALL_CANCEL (pwrite, fd, buf, count, 0, offset >> 31, offset);
 }
 
 strong_alias (__libc_pwrite, __pwrite)
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/pwrite64.c b/sysdeps/unix/sysv/linux/powerpc/powerpc32/pwrite64.c
index 67b726e..462a5cc 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/pwrite64.c
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/pwrite64.c
@@ -26,28 +26,9 @@ 
 ssize_t
 __libc_pwrite64 (int fd, const void *buf, size_t count, off64_t offset)
 {
-  ssize_t result;
-
-  if (SINGLE_THREAD_P)
-    {
   /* On PPC32 64bit values are aligned in odd/even register pairs.  */
-      result = INLINE_SYSCALL (pwrite, 6, fd, buf, count,
-			       0, (long) (offset >> 32),
-			       (long) offset);
-
-      return result;
-    }
-
-  int oldtype = LIBC_CANCEL_ASYNC ();
-
-  /* On PPC32 64bit values are aligned in odd/even register pairs.  */
-  result = INLINE_SYSCALL (pwrite, 6, fd, buf, count,
-			   0, (long) (offset >> 32),
-			   (long) offset);
-
-  LIBC_CANCEL_RESET (oldtype);
-
-  return result;
+  return SYSCALL_CANCEL (pwrite, fd, buf, count, 0, (long) (offset >> 32),
+			 (long) offset);
 }
 
 weak_alias (__libc_pwrite64, __pwrite64)
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/socket.S b/sysdeps/unix/sysv/linux/powerpc/powerpc32/socket.S
index 2261484..601852b 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/socket.S
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/socket.S
@@ -40,7 +40,7 @@ 
 
 /* 0(r1) and 4(r1) are reserved by the ABI, 8(r1), 12(r1), 16(r1) are used
    for temp saves.  44(r1) is used to save r30.  */
-#define stackblock 20
+#define STACKBLOCK 20
 
 #ifndef __socket
 # ifndef NO_WEAK_ALIAS
@@ -55,63 +55,42 @@  ENTRY(__socket)
 	stwu r1,-48(r1)
 	cfi_adjust_cfa_offset(48)
 #if NARGS >= 1
-	stw  r3,stackblock(r1)
+	stw  r3,STACKBLOCK(r1)
 #endif
 #if NARGS >= 2
-	stw  r4,4+stackblock(r1)
+	stw  r4,4+STACKBLOCK(r1)
 #endif
 #if NARGS >= 3
-	stw  r5,8+stackblock(r1)
+	stw  r5,8+STACKBLOCK(r1)
 #endif
 #if NARGS >= 4
-	stw  r6,12+stackblock(r1)
+	stw  r6,12+STACKBLOCK(r1)
 #endif
 #if NARGS >= 5
-	stw  r7,16+stackblock(r1)
+	stw  r7,16+STACKBLOCK(r1)
 #endif
 #if NARGS >= 6
-	stw  r8,20+stackblock(r1)
+	stw  r8,20+STACKBLOCK(r1)
 #endif
 #if NARGS >= 7
 #error too many arguments!
 #endif
-
-#if defined NEED_CANCELLATION && defined CENABLE
-	SINGLE_THREAD_P
-	bne-	.Lsocket_cancel
-#endif
-
-	li	r3,P(SOCKOP_,socket)
-	addi	r4,r1,stackblock
-	DO_CALL(SYS_ify(socketcall))
-	addi	r1,r1,48
-	PSEUDO_RET
-
-#if defined NEED_CANCELLATION && defined CENABLE
-.Lsocket_cancel:
 	mflr	r9
+	SETUP_PIC;
 	stw	r9,52(r1)
 	cfi_offset (lr, 4)
-	CENABLE
-	stw	r3,16(r1)
-	li	r3,P(SOCKOP_,socket)
-	addi	r4,r1,stackblock
-	DO_CALL(SYS_ify(socketcall))
-	mfcr	r0
-	stw	r3,8(r1)
-	stw	r0,12(r1)
-	lwz	r3,16(r1)
-	CDISABLE
-	lwz	r4,52(r1)
-	lwz	r0,12(r1)
-	lwz	r3,8(r1)
-	mtlr	r4
-	mtcr	r0
-	addi	r1,r1,48
-	PSEUDO_RET
-#endif
 
-PSEUDO_END (__socket)
+	li	r3,SYS_ify(socketcall)
+	li	r4,P(SOCKOP_,socket)
+	addi	r5,r1,STACKBLOCK
+	CANCEL_JUMPTARGET
+	lwz	r9,52(r1)
+	addi	r1,r1,48
+	cfi_adjust_cfa_offset(-48)
+	mtlr	r9
+	cfi_restore(lr)
+	b	__syscall_cancel_error@local;
+END (__socket)
 
 #ifndef NO_WEAK_ALIAS
 weak_alias (__socket, socket)
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h b/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h
index b6eedcb..a65de6d 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h
@@ -25,89 +25,56 @@ 
 
 #if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
 
+# ifdef NOT_IN_libc
+#  define SETUP_PIC							\
+    bcl     20,31,got_label;						\
+got_label:
+
+#  define CANCEL_JUMPTARGET						\
+    stw   r30,8(r1);							\
+    mflr  r30;								\
+    addis r30,r30,_GLOBAL_OFFSET_TABLE_-got_label@ha;			\
+    addi  r30,r30,_GLOBAL_OFFSET_TABLE_-got_label@l;			\
+    bl    __syscall_cancel@plt;						\
+    lwz   r30,8(r1)
+# else
+#  define SETUP_PIC
+#  if defined SHARED && defined PIC
+#   define CANCEL_JUMPTARGET						\
+    bl    __GI___syscall_cancel@locaL
+#  else
+#   define CANCEL_JUMPTARGET						\
+    bl    __syscall_cancel
+#  endif
+# endif
+
 # undef PSEUDO
 # define PSEUDO(name, syscall_name, args)				\
   .section ".text";							\
   ENTRY (name)								\
-    SINGLE_THREAD_P;							\
-    bne- .Lpseudo_cancel;						\
-  .type __##syscall_name##_nocancel,@function;				\
-  .globl __##syscall_name##_nocancel;					\
-  __##syscall_name##_nocancel:						\
-    DO_CALL (SYS_ify (syscall_name));					\
-    PSEUDO_RET;								\
-  .size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel;	\
-  .Lpseudo_cancel:							\
-    stwu 1,-48(1);							\
-    cfi_adjust_cfa_offset (48);						\
-    mflr 9;								\
-    stw 9,52(1);							\
+    stwu r1,-16(r1);							\
+    cfi_adjust_cfa_offset (16);						\
+    mflr r0;								\
+    SETUP_PIC;								\
+    stw  r0,20(r1);							\
     cfi_offset (lr, 4);							\
-    DOCARGS_##args;	/* save syscall args around CENABLE.  */	\
-    CENABLE;								\
-    stw 3,16(1);	/* store CENABLE return value (MASK).  */	\
-    UNDOCARGS_##args;	/* restore syscall args.  */			\
-    DO_CALL (SYS_ify (syscall_name));					\
-    mfcr 0;		/* save CR/R3 around CDISABLE.  */		\
-    stw 3,8(1);								\
-    stw 0,12(1);							\
-    lwz 3,16(1);	/* pass MASK to CDISABLE.  */			\
-    CDISABLE;								\
-    lwz 4,52(1);							\
-    lwz 0,12(1);	/* restore CR/R3. */				\
-    lwz 3,8(1);								\
-    mtlr 4;								\
-    mtcr 0;								\
-    addi 1,1,48;
-
-# define DOCARGS_0
-# define UNDOCARGS_0
-
-# define DOCARGS_1	stw 3,20(1); DOCARGS_0
-# define UNDOCARGS_1	lwz 3,20(1); UNDOCARGS_0
-
-# define DOCARGS_2	stw 4,24(1); DOCARGS_1
-# define UNDOCARGS_2	lwz 4,24(1); UNDOCARGS_1
-
-# define DOCARGS_3	stw 5,28(1); DOCARGS_2
-# define UNDOCARGS_3	lwz 5,28(1); UNDOCARGS_2
-
-# define DOCARGS_4	stw 6,32(1); DOCARGS_3
-# define UNDOCARGS_4	lwz 6,32(1); UNDOCARGS_3
-
-# define DOCARGS_5	stw 7,36(1); DOCARGS_4
-# define UNDOCARGS_5	lwz 7,36(1); UNDOCARGS_4
-
-# define DOCARGS_6	stw 8,40(1); DOCARGS_5
-# define UNDOCARGS_6	lwz 8,40(1); UNDOCARGS_5
-
-# ifdef IS_IN_libpthread
-#  define CENABLE	bl __pthread_enable_asynccancel@local
-#  define CDISABLE	bl __pthread_disable_asynccancel@local
-# elif !defined NOT_IN_libc
-#  define CENABLE	bl __libc_enable_asynccancel@local
-#  define CDISABLE	bl __libc_disable_asynccancel@local
-# elif defined IS_IN_librt
-#  define CENABLE	bl __librt_enable_asynccancel@local
-#  define CDISABLE	bl __librt_disable_asynccancel@local
-# else
-#  error Unsupported library
-# endif
-
-# ifndef __ASSEMBLER__
-#  define SINGLE_THREAD_P						\
-  __builtin_expect (THREAD_GETMEM (THREAD_SELF,				\
-				   header.multiple_threads) == 0, 1)
-# else
-#  define SINGLE_THREAD_P						\
-  lwz 10,MULTIPLE_THREADS_OFFSET(2);					\
-  cmpwi 10,0
-# endif
-
-#elif !defined __ASSEMBLER__
-
-# define SINGLE_THREAD_P (1)
-# define NO_CANCELLATION 1
+    mr   r9,r8;								\
+    mr   r8,r7;								\
+    mr   r7,r6;								\
+    mr   r6,r5;								\
+    mr   r5,r4;								\
+    mr   r4,r3;								\
+    li   r3,SYS_ify (syscall_name);					\
+    CANCEL_JUMPTARGET;							\
+    lwz  r0,20(r1);							\
+    addi r1,r1,16;							\
+    cfi_adjust_cfa_offset (-16);					\
+    mtlr r0;								\
+    cfi_restore (lr);
+
+# undef PSEUDO_RET
+# define PSEUDO_RET							\
+    b    __syscall_cancel_error@local;
 
 #endif
 
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h b/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h
index 1a5e37a..7701d66 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h
@@ -168,6 +168,14 @@ 
     sc_ret;								\
   })
 
+#undef SYSCALL_CANCEL_ERROR
+#define SYSCALL_CANCEL_ERROR(err)					\
+  (err > 0xfffffffffffff000UL)
+
+#undef SYSCALL_CANCEL_ERRNO
+#define SYSCALL_CANCEL_ERRNO(err)					\
+  (-err)
+
 /* Define a macro which expands inline into the wrapper code for a system
    call. This use is for internal calls that do not need to handle errors
    normally. It will never touch errno.
diff --git a/sysdeps/unix/sysv/linux/preadv.c b/sysdeps/unix/sysv/linux/preadv.c
index 0b2e9ed..c353b78 100644
--- a/sysdeps/unix/sysv/linux/preadv.c
+++ b/sysdeps/unix/sysv/linux/preadv.c
@@ -53,18 +53,8 @@  PREADV (int fd, const struct iovec *vector, int count, OFF_T offset)
 #ifdef __NR_preadv
   ssize_t result;
 
-  if (SINGLE_THREAD_P)
-    result = INLINE_SYSCALL (preadv, 5, fd, vector, count,
-			     LO_HI_LONG (offset));
-  else
-    {
-      int oldtype = LIBC_CANCEL_ASYNC ();
-
-      result = INLINE_SYSCALL (preadv, 5, fd, vector, count,
-			       LO_HI_LONG (offset));
-
-      LIBC_CANCEL_RESET (oldtype);
-    }
+  result = SYSCALL_CANCEL (preadv, fd, vector, count,
+			   LO_HI_LONG (offset));
 # ifdef __ASSUME_PREADV
   return result;
 # endif
diff --git a/sysdeps/unix/sysv/linux/pwritev.c b/sysdeps/unix/sysv/linux/pwritev.c
index 518db33..8f4e38a 100644
--- a/sysdeps/unix/sysv/linux/pwritev.c
+++ b/sysdeps/unix/sysv/linux/pwritev.c
@@ -53,18 +53,8 @@  PWRITEV (int fd, const struct iovec *vector, int count, OFF_T offset)
 #ifdef __NR_pwritev
   ssize_t result;
 
-  if (SINGLE_THREAD_P)
-    result = INLINE_SYSCALL (pwritev, 5, fd, vector, count,
-			     LO_HI_LONG (offset));
-  else
-    {
-      int oldtype = LIBC_CANCEL_ASYNC ();
-
-      result = INLINE_SYSCALL (pwritev, 5, fd, vector, count,
-			     LO_HI_LONG (offset));
-
-      LIBC_CANCEL_RESET (oldtype);
-    }
+  result = INLINE_SYSCALL (pwritev, 5, fd, vector, count,
+			   LO_HI_LONG (offset));
 # ifdef __ASSUME_PWRITEV
   return result;
 # endif
diff --git a/sysdeps/unix/sysv/linux/sync_file_range.c b/sysdeps/unix/sysv/linux/sync_file_range.c
index 1068465..beb69a6 100644
--- a/sysdeps/unix/sysv/linux/sync_file_range.c
+++ b/sysdeps/unix/sysv/linux/sync_file_range.c
@@ -28,43 +28,18 @@ 
 int
 sync_file_range (int fd, __off64_t from, __off64_t to, unsigned int flags)
 {
-  if (SINGLE_THREAD_P)
-    return INLINE_SYSCALL (sync_file_range, 6, fd,
-			   __LONG_LONG_PAIR ((long) (from >> 32), (long) from),
-			   __LONG_LONG_PAIR ((long) (to >> 32), (long) to),
-			   flags);
-
-  int result;
-  int oldtype = LIBC_CANCEL_ASYNC ();
-
-  result = INLINE_SYSCALL (sync_file_range, 6, fd,
-			   __LONG_LONG_PAIR ((long) (from >> 32), (long) from),
-			   __LONG_LONG_PAIR ((long) (to >> 32), (long) to),
-			   flags);
-
-  LIBC_CANCEL_RESET (oldtype);
-
-  return result;
+  return SYSCALL_CANCEL (sync_file_range, fd,
+			 __LONG_LONG_PAIR ((long) (from >> 32), (long) from),
+			 __LONG_LONG_PAIR ((long) (to >> 32), (long) to),
+			 flags);
 }
 #elif defined __NR_sync_file_range2
 int
 sync_file_range (int fd, __off64_t from, __off64_t to, unsigned int flags)
 {
-  if (SINGLE_THREAD_P)
-    return INLINE_SYSCALL (sync_file_range2, 6, fd, flags,
-			   __LONG_LONG_PAIR ((long) (from >> 32), (long) from),
-			   __LONG_LONG_PAIR ((long) (to >> 32), (long) to));
-
-  int result;
-  int oldtype = LIBC_CANCEL_ASYNC ();
-
-  result = INLINE_SYSCALL (sync_file_range2, 6, fd, flags,
-			   __LONG_LONG_PAIR ((long) (from >> 32), (long) from),
-			   __LONG_LONG_PAIR ((long) (to >> 32), (long) to));
-
-  LIBC_CANCEL_RESET (oldtype);
-
-  return result;
+  return SYSCALL_CANCEL (sync_file_range2, fd, flags,
+			 __LONG_LONG_PAIR ((long) (from >> 32), (long) from),
+			 __LONG_LONG_PAIR ((long) (to >> 32), (long) to));
 }
 #else
 int