From: Shan Hai <haishan.bai@gmail.com> To: benh@kernel.crashing.org, paulus@samba.org Cc: tglx@linutronix.de, walken@google.com, dhowells@redhat.com, cmetcalf@tilera.com, tony.luck@intel.com, akpm@linux-foundation.org, a.p.zijlstra@chello.nl, linuxppc-dev@lists.ozlabs.org, linux-kernel@vger.kernel.org Subject: [PATCH 0/1] Fixup write permission of TLB on powerpc e500 core Date: Fri, 15 Jul 2011 16:07:17 +0800 [thread overview] Message-ID: <1310717238-13857-1-git-send-email-haishan.bai@gmail.com> (raw) The following test case could reveal a bug in the futex_lock_pi() BUG: On FUTEX_LOCK_PI, there is a infinite loop in the futex_lock_pi() on Powerpc e500 core. Cause: The linux kernel on the e500 core has no write permission on the COW page, refer the head comment of the following test code. ftrace on test case: [000] 353.990181: futex_lock_pi_atomic <-futex_lock_pi [000] 353.990185: cmpxchg_futex_value_locked <-futex_lock_pi_atomic [snip] [000] 353.990191: do_page_fault <-handle_page_fault [000] 353.990192: bad_page_fault <-handle_page_fault [000] 353.990193: search_exception_tables <-bad_page_fault [snip] [000] 353.990199: get_user_pages <-fault_in_user_writeable [snip] [000] 353.990208: mark_page_accessed <-follow_page [000] 353.990222: futex_lock_pi_atomic <-futex_lock_pi [snip] [000] 353.990230: cmpxchg_futex_value_locked <-futex_lock_pi_atomic [ a loop occures here ] /* * A test case for revealing an infinite loop in the futex_lock_pi(). * - there are 2 processes, parent and a child * - the parent process allocates and initializes a pthread_mutex MUTEX in a * shared memory region * - the parent process holds the MUTEX and do long time computing * - the child process tries to hold the MUTEX during the parent holding it and * traps into the kernel for waiting on the MUTEX because of contention * - the kernel loops in futex_lock_pi() * - result of 'top' command reveals that the system usage of CPU is 100% */ #include <stdio.h> #include <stdlib.h> #include <sys/ipc.h> #include <sys/shm.h> #include <errno.h> #include <pthread.h> #include <string.h> #include <signal.h> #include <fcntl.h> #include <sys/types.h> #include <sys/mman.h> enum { SHM_INIT, SHM_GET }; enum { PARENT, CHILD }; #define FIXED_MMAP_ADDR 0x20000000 #define MMAP_SIZE 0x2000000 static int shmid; static char shm_name[100]; static int sleep_period = 100000; void * shmem_init(int flag) { int start = FIXED_MMAP_ADDR; int memory_size = MMAP_SIZE; int mode = 0666; void *addr; int ret; sprintf(shm_name, "/shmem_1234"); shmid = shm_open (shm_name, O_RDWR | O_EXCL | O_CREAT | O_TRUNC, mode); if (shmid < 0) { if (errno == EEXIST) { printf ("shm_open: %s\n", strerror(errno)); shmid = shm_open (shm_name, O_RDWR, mode); } else { printf("failed to shm_open, err=%s\n", strerror(errno)); return NULL; } } ret = fcntl (shmid, F_SETFD, FD_CLOEXEC); if (ret < 0) { printf("fcntl: %s\n", strerror(errno)); return NULL; } ret = ftruncate (shmid, memory_size); if (ret < 0) { printf("ftruncate: %s\n", strerror(errno)); return NULL; } addr = mmap ((void *)start, memory_size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, shmid, 0); if (addr == MAP_FAILED) { printf ("mmap: %s\n", strerror(errno)); close (shmid); shm_unlink (shm_name); return NULL; } if (flag == SHM_INIT) memset(addr, 0, memory_size); return (void *)start; } pthread_mutex_t * shmem_mutex_init(int flag) { pthread_mutex_t * pmutex = (pthread_mutex_t *)shmem_init(flag); pthread_mutexattr_t attr; if (flag == SHM_INIT) { pthread_mutexattr_init (&attr); pthread_mutexattr_setpshared (&attr, PTHREAD_PROCESS_SHARED); pthread_mutexattr_setprotocol (&attr, PTHREAD_PRIO_INHERIT); pthread_mutexattr_setrobust_np (&attr, PTHREAD_MUTEX_STALLED_NP); pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_ERRORCHECK); if (pthread_mutex_init (pmutex, &attr) != 0) { printf("Init mutex failed, err=%s\n", strerror(errno)); pthread_mutexattr_destroy (&attr); return NULL; } } return pmutex; } void long_running_task(int flag) { static int counter = 0; if (flag == PARENT) usleep(5*sleep_period); else usleep(3*sleep_period); counter = (counter + 1) % 100; printf("%d: completed %d computing\n", getpid(), counter); } void sig_handler(int signum) { close(shmid); shm_unlink(shm_name); exit(0); } int main(int argc, char *argv[]) { pthread_mutex_t *mutex_parent, *mutex_child; signal(SIGUSR1, sig_handler); if (fork()) { /* parent process */ if ((mutex_parent = shmem_mutex_init(SHM_INIT)) == NULL) { printf("failed to get the shmem_mutex\n"); exit(-1); } while (1) { printf("%d: try to hold the lock\n", getpid()); pthread_mutex_lock(mutex_parent); printf("%d: got the lock\n", getpid()); long_running_task(PARENT); pthread_mutex_unlock(mutex_parent); printf("%d: released the lock\n", getpid()); } } else { /* child process */ usleep(sleep_period); if ((mutex_child = shmem_mutex_init(SHM_GET)) == NULL) { printf("failed to get the shmem_mutex\n"); exit(-1); } while (1) { printf("%d: try to hold the lock\n", getpid()); pthread_mutex_lock(mutex_child); printf("%d: got the lock\n", getpid()); long_running_task(CHILD); pthread_mutex_unlock(mutex_child); printf("%d: released the lock\n", getpid()); } } return 0; } --- arch/powerpc/include/asm/futex.h | 11 ++++++++++- arch/powerpc/include/asm/tlb.h | 25 +++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletions(-)
WARNING: multiple messages have this Message-ID (diff)
From: Shan Hai <haishan.bai@gmail.com> To: benh@kernel.crashing.org, paulus@samba.org Cc: tony.luck@intel.com, a.p.zijlstra@chello.nl, linux-kernel@vger.kernel.org, cmetcalf@tilera.com, dhowells@redhat.com, tglx@linutronix.de, walken@google.com, linuxppc-dev@lists.ozlabs.org, akpm@linux-foundation.org Subject: [PATCH 0/1] Fixup write permission of TLB on powerpc e500 core Date: Fri, 15 Jul 2011 16:07:17 +0800 [thread overview] Message-ID: <1310717238-13857-1-git-send-email-haishan.bai@gmail.com> (raw) The following test case could reveal a bug in the futex_lock_pi() BUG: On FUTEX_LOCK_PI, there is a infinite loop in the futex_lock_pi() on Powerpc e500 core. Cause: The linux kernel on the e500 core has no write permission on the COW page, refer the head comment of the following test code. ftrace on test case: [000] 353.990181: futex_lock_pi_atomic <-futex_lock_pi [000] 353.990185: cmpxchg_futex_value_locked <-futex_lock_pi_atomic [snip] [000] 353.990191: do_page_fault <-handle_page_fault [000] 353.990192: bad_page_fault <-handle_page_fault [000] 353.990193: search_exception_tables <-bad_page_fault [snip] [000] 353.990199: get_user_pages <-fault_in_user_writeable [snip] [000] 353.990208: mark_page_accessed <-follow_page [000] 353.990222: futex_lock_pi_atomic <-futex_lock_pi [snip] [000] 353.990230: cmpxchg_futex_value_locked <-futex_lock_pi_atomic [ a loop occures here ] /* * A test case for revealing an infinite loop in the futex_lock_pi(). * - there are 2 processes, parent and a child * - the parent process allocates and initializes a pthread_mutex MUTEX in a * shared memory region * - the parent process holds the MUTEX and do long time computing * - the child process tries to hold the MUTEX during the parent holding it and * traps into the kernel for waiting on the MUTEX because of contention * - the kernel loops in futex_lock_pi() * - result of 'top' command reveals that the system usage of CPU is 100% */ #include <stdio.h> #include <stdlib.h> #include <sys/ipc.h> #include <sys/shm.h> #include <errno.h> #include <pthread.h> #include <string.h> #include <signal.h> #include <fcntl.h> #include <sys/types.h> #include <sys/mman.h> enum { SHM_INIT, SHM_GET }; enum { PARENT, CHILD }; #define FIXED_MMAP_ADDR 0x20000000 #define MMAP_SIZE 0x2000000 static int shmid; static char shm_name[100]; static int sleep_period = 100000; void * shmem_init(int flag) { int start = FIXED_MMAP_ADDR; int memory_size = MMAP_SIZE; int mode = 0666; void *addr; int ret; sprintf(shm_name, "/shmem_1234"); shmid = shm_open (shm_name, O_RDWR | O_EXCL | O_CREAT | O_TRUNC, mode); if (shmid < 0) { if (errno == EEXIST) { printf ("shm_open: %s\n", strerror(errno)); shmid = shm_open (shm_name, O_RDWR, mode); } else { printf("failed to shm_open, err=%s\n", strerror(errno)); return NULL; } } ret = fcntl (shmid, F_SETFD, FD_CLOEXEC); if (ret < 0) { printf("fcntl: %s\n", strerror(errno)); return NULL; } ret = ftruncate (shmid, memory_size); if (ret < 0) { printf("ftruncate: %s\n", strerror(errno)); return NULL; } addr = mmap ((void *)start, memory_size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, shmid, 0); if (addr == MAP_FAILED) { printf ("mmap: %s\n", strerror(errno)); close (shmid); shm_unlink (shm_name); return NULL; } if (flag == SHM_INIT) memset(addr, 0, memory_size); return (void *)start; } pthread_mutex_t * shmem_mutex_init(int flag) { pthread_mutex_t * pmutex = (pthread_mutex_t *)shmem_init(flag); pthread_mutexattr_t attr; if (flag == SHM_INIT) { pthread_mutexattr_init (&attr); pthread_mutexattr_setpshared (&attr, PTHREAD_PROCESS_SHARED); pthread_mutexattr_setprotocol (&attr, PTHREAD_PRIO_INHERIT); pthread_mutexattr_setrobust_np (&attr, PTHREAD_MUTEX_STALLED_NP); pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_ERRORCHECK); if (pthread_mutex_init (pmutex, &attr) != 0) { printf("Init mutex failed, err=%s\n", strerror(errno)); pthread_mutexattr_destroy (&attr); return NULL; } } return pmutex; } void long_running_task(int flag) { static int counter = 0; if (flag == PARENT) usleep(5*sleep_period); else usleep(3*sleep_period); counter = (counter + 1) % 100; printf("%d: completed %d computing\n", getpid(), counter); } void sig_handler(int signum) { close(shmid); shm_unlink(shm_name); exit(0); } int main(int argc, char *argv[]) { pthread_mutex_t *mutex_parent, *mutex_child; signal(SIGUSR1, sig_handler); if (fork()) { /* parent process */ if ((mutex_parent = shmem_mutex_init(SHM_INIT)) == NULL) { printf("failed to get the shmem_mutex\n"); exit(-1); } while (1) { printf("%d: try to hold the lock\n", getpid()); pthread_mutex_lock(mutex_parent); printf("%d: got the lock\n", getpid()); long_running_task(PARENT); pthread_mutex_unlock(mutex_parent); printf("%d: released the lock\n", getpid()); } } else { /* child process */ usleep(sleep_period); if ((mutex_child = shmem_mutex_init(SHM_GET)) == NULL) { printf("failed to get the shmem_mutex\n"); exit(-1); } while (1) { printf("%d: try to hold the lock\n", getpid()); pthread_mutex_lock(mutex_child); printf("%d: got the lock\n", getpid()); long_running_task(CHILD); pthread_mutex_unlock(mutex_child); printf("%d: released the lock\n", getpid()); } } return 0; } --- arch/powerpc/include/asm/futex.h | 11 ++++++++++- arch/powerpc/include/asm/tlb.h | 25 +++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletions(-)
next reply other threads:[~2011-07-15 8:05 UTC|newest] Thread overview: 138+ messages / expand[flat|nested] mbox.gz Atom feed top 2011-07-15 8:07 Shan Hai [this message] 2011-07-15 8:07 ` [PATCH 0/1] Fixup write permission of TLB on powerpc e500 core Shan Hai 2011-07-15 8:07 ` [PATCH 1/1] " Shan Hai 2011-07-15 8:07 ` Shan Hai 2011-07-15 10:23 ` Peter Zijlstra 2011-07-15 10:23 ` Peter Zijlstra 2011-07-15 15:18 ` Shan Hai 2011-07-15 15:18 ` Shan Hai 2011-07-15 15:24 ` Peter Zijlstra 2011-07-15 15:24 ` Peter Zijlstra 2011-07-16 15:36 ` Shan Hai 2011-07-16 15:36 ` Shan Hai 2011-07-16 14:50 ` Shan Hai 2011-07-16 14:50 ` Shan Hai 2011-07-16 23:49 ` Benjamin Herrenschmidt 2011-07-16 23:49 ` Benjamin Herrenschmidt 2011-07-17 9:38 ` Peter Zijlstra 2011-07-17 9:38 ` Peter Zijlstra 2011-07-17 14:29 ` Benjamin Herrenschmidt 2011-07-17 14:29 ` Benjamin Herrenschmidt 2011-07-17 23:14 ` Benjamin Herrenschmidt 2011-07-17 23:14 ` Benjamin Herrenschmidt 2011-07-18 3:53 ` Benjamin Herrenschmidt 2011-07-18 3:53 ` Benjamin Herrenschmidt 2011-07-18 4:02 ` Benjamin Herrenschmidt 2011-07-18 4:02 ` Benjamin Herrenschmidt 2011-07-18 4:01 ` Benjamin Herrenschmidt 2011-07-18 4:01 ` Benjamin Herrenschmidt 2011-07-18 6:48 ` Shan Hai 2011-07-18 6:48 ` Shan Hai 2011-07-18 7:01 ` Benjamin Herrenschmidt 2011-07-18 7:01 ` Benjamin Herrenschmidt 2011-07-18 7:26 ` Shan Hai 2011-07-18 7:26 ` Shan Hai 2011-07-18 7:36 ` Benjamin Herrenschmidt 2011-07-18 7:36 ` Benjamin Herrenschmidt 2011-07-18 7:50 ` Shan Hai 2011-07-18 7:50 ` Shan Hai 2011-07-19 3:30 ` Shan Hai 2011-07-19 3:30 ` Shan Hai 2011-07-19 4:20 ` Benjamin Herrenschmidt 2011-07-19 4:20 ` Benjamin Herrenschmidt 2011-07-19 4:29 ` [RFC/PATCH] mm/futex: Fix futex writes on archs with SW tracking of dirty & young Benjamin Herrenschmidt 2011-07-19 4:29 ` Benjamin Herrenschmidt 2011-07-19 4:55 ` Shan Hai 2011-07-19 4:55 ` Shan Hai 2011-07-19 5:17 ` Shan Hai 2011-07-19 5:17 ` Shan Hai 2011-07-19 5:24 ` Benjamin Herrenschmidt 2011-07-19 5:24 ` Benjamin Herrenschmidt 2011-07-19 5:38 ` Shan Hai 2011-07-19 5:38 ` Shan Hai 2011-07-19 7:46 ` Benjamin Herrenschmidt 2011-07-19 7:46 ` Benjamin Herrenschmidt 2011-07-19 8:24 ` Shan Hai 2011-07-19 8:24 ` Shan Hai 2011-07-19 8:26 ` [RFC/PATCH] mm/futex: Fix futex writes on archs with SW trackingof " David Laight 2011-07-19 8:26 ` David Laight 2011-07-19 8:45 ` Benjamin Herrenschmidt 2011-07-19 8:45 ` Benjamin Herrenschmidt 2011-07-19 8:45 ` Shan Hai 2011-07-19 8:45 ` Shan Hai 2011-07-19 11:10 ` [RFC/PATCH] mm/futex: Fix futex writes on archs with SW tracking of " Peter Zijlstra 2011-07-19 11:10 ` Peter Zijlstra 2011-07-20 14:39 ` Darren Hart 2011-07-20 14:39 ` Darren Hart 2011-07-21 22:36 ` Andrew Morton 2011-07-21 22:36 ` Andrew Morton 2011-07-21 22:52 ` Benjamin Herrenschmidt 2011-07-21 22:52 ` Benjamin Herrenschmidt 2011-07-21 22:57 ` Benjamin Herrenschmidt 2011-07-21 22:57 ` Benjamin Herrenschmidt 2011-07-21 22:59 ` Andrew Morton 2011-07-21 22:59 ` Andrew Morton 2011-07-22 1:40 ` Benjamin Herrenschmidt 2011-07-22 1:40 ` Benjamin Herrenschmidt 2011-07-22 1:54 ` Shan Hai 2011-07-22 1:54 ` Shan Hai 2011-07-27 6:50 ` Mike Frysinger 2011-07-27 6:50 ` Mike Frysinger 2011-07-27 7:58 ` Benjamin Herrenschmidt 2011-07-27 7:58 ` Benjamin Herrenschmidt 2011-07-27 8:59 ` Peter Zijlstra 2011-07-27 8:59 ` Peter Zijlstra 2011-07-27 10:09 ` David Howells 2011-07-27 10:09 ` David Howells 2011-07-27 10:17 ` Peter Zijlstra 2011-07-27 10:17 ` Peter Zijlstra 2011-07-27 10:20 ` Benjamin Herrenschmidt 2011-07-27 10:20 ` Benjamin Herrenschmidt 2011-07-28 0:12 ` Mike Frysinger 2011-07-28 0:12 ` Mike Frysinger 2011-08-08 2:31 ` Mike Frysinger 2011-08-08 2:31 ` Mike Frysinger 2011-07-28 10:55 ` David Howells 2011-07-28 10:55 ` David Howells 2011-07-17 11:02 ` [PATCH 1/1] Fixup write permission of TLB on powerpc e500 core Peter Zijlstra 2011-07-17 11:02 ` Peter Zijlstra 2011-07-17 13:33 ` Shan Hai 2011-07-17 13:33 ` Shan Hai 2011-07-17 14:48 ` Benjamin Herrenschmidt 2011-07-17 14:48 ` Benjamin Herrenschmidt 2011-07-17 15:40 ` Shan Hai 2011-07-17 15:40 ` Shan Hai 2011-07-17 22:34 ` Benjamin Herrenschmidt 2011-07-17 22:34 ` Benjamin Herrenschmidt 2011-07-17 14:34 ` Benjamin Herrenschmidt 2011-07-17 14:34 ` Benjamin Herrenschmidt 2011-07-15 8:20 ` [PATCH 0/1] " Peter Zijlstra 2011-07-15 8:20 ` Peter Zijlstra 2011-07-15 8:38 ` MailingLists 2011-07-15 8:38 ` MailingLists 2011-07-15 8:44 ` Peter Zijlstra 2011-07-15 8:44 ` Peter Zijlstra 2011-07-15 9:08 ` Shan Hai 2011-07-15 9:08 ` Shan Hai 2011-07-15 9:12 ` Benjamin Herrenschmidt 2011-07-15 9:12 ` Benjamin Herrenschmidt 2011-07-15 9:50 ` Peter Zijlstra 2011-07-15 9:50 ` Peter Zijlstra 2011-07-15 10:06 ` Shan Hai 2011-07-15 10:06 ` Shan Hai 2011-07-15 10:32 ` David Laight 2011-07-15 10:32 ` David Laight 2011-07-15 10:39 ` Peter Zijlstra 2011-07-15 10:39 ` Peter Zijlstra 2011-07-15 15:32 ` Shan Hai 2011-07-15 15:32 ` Shan Hai 2011-07-16 0:20 ` Benjamin Herrenschmidt 2011-07-16 0:20 ` Benjamin Herrenschmidt 2011-07-16 15:03 ` Shan Hai 2011-07-16 15:03 ` Shan Hai 2011-07-15 23:47 ` Benjamin Herrenschmidt 2011-07-15 23:47 ` Benjamin Herrenschmidt 2011-07-15 9:07 ` Benjamin Herrenschmidt 2011-07-15 9:07 ` Benjamin Herrenschmidt 2011-07-15 9:05 ` Benjamin Herrenschmidt 2011-07-15 9:05 ` Benjamin Herrenschmidt
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=1310717238-13857-1-git-send-email-haishan.bai@gmail.com \ --to=haishan.bai@gmail.com \ --cc=a.p.zijlstra@chello.nl \ --cc=akpm@linux-foundation.org \ --cc=benh@kernel.crashing.org \ --cc=cmetcalf@tilera.com \ --cc=dhowells@redhat.com \ --cc=linux-kernel@vger.kernel.org \ --cc=linuxppc-dev@lists.ozlabs.org \ --cc=paulus@samba.org \ --cc=tglx@linutronix.de \ --cc=tony.luck@intel.com \ --cc=walken@google.com \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.