All of lore.kernel.org
 help / color / mirror / Atom feed
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(-)

             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: link
Be 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.