Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[PATCH] NOMMU: Make futexes work under NOMMU conditions

Make futexes work under NOMMU conditions.

This can be tested by running this in one shell:

#define SYSERROR(X, Y) \
do { if ((long)(X) == -1L) { perror(Y); exit(1); }} while(0)

int main()
{
int shmid, tmp, *f, n;

shmid = shmget(23, 4, IPC_CREAT|0666);
SYSERROR(shmid, "shmget");

f = shmat(shmid, NULL, 0);
SYSERROR(f, "shmat");

n = *f;
printf("WAIT: %p{%x}\n", f, n);
tmp = futex(f, FUTEX_WAIT, n, NULL, NULL, 0);
SYSERROR(tmp, "futex");
printf("WAITED: %d\n", tmp);

tmp = shmdt(f);
SYSERROR(tmp, "shmdt");

exit(0);
}

And then this in the other shell:

#define SYSERROR(X, Y) \
do { if ((long)(X) == -1L) { perror(Y); exit(1); }} while(0)

int main()
{
int shmid, tmp, *f;

shmid = shmget(23, 4, IPC_CREAT|0666);
SYSERROR(shmid, "shmget");

f = shmat(shmid, NULL, 0);
SYSERROR(f, "shmat");

(*f)++;
printf("WAKE: %p{%x}\n", f, *f);
tmp = futex(f, FUTEX_WAKE, 1, NULL, NULL, 0);
SYSERROR(tmp, "futex");
printf("WOKE: %d\n", tmp);

tmp = shmdt(f);
SYSERROR(tmp, "shmdt");

exit(0);
}

The first program will set up a SYSV IPC SHM segment and wait on a futex in it
for the number at the start to change. The program will increment that number
and wake the first program up. This leads to output of the form:

SHELL 1 SHELL 2
======================= =======================
# /dowait
WAIT: 0xc32ac000{0}
# /dowake
WAKE: 0xc32ac000{1}
WAITED: 0 WOKE: 1

Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by

David Howells and committed by
Linus Torvalds
930e652a 0112c4c6

+19 -5
+10
Documentation/nommu-mmap.txt
··· 138 138 on ramfs or tmpfs mounts. 139 139 140 140 141 + ======= 142 + FUTEXES 143 + ======= 144 + 145 + Futexes are supported in NOMMU mode if the arch supports them. An error will 146 + be given if an address passed to the futex system call lies outside the 147 + mappings made by a process or if the mapping in which the address lies does not 148 + support futexes (such as an I/O chardev mapping). 149 + 150 + 141 151 ============= 142 152 NO-MMU MREMAP 143 153 =============
+9 -5
mm/nommu.c
··· 350 350 EXPORT_SYMBOL(find_vma); 351 351 352 352 /* 353 + * find a VMA 354 + * - we don't extend stack VMAs under NOMMU conditions 355 + */ 356 + struct vm_area_struct *find_extend_vma(struct mm_struct *mm, unsigned long addr) 357 + { 358 + return find_vma(mm, addr); 359 + } 360 + 361 + /* 353 362 * look up the first VMA exactly that exactly matches addr 354 363 * - should be called with mm->mmap_sem at least held readlocked 355 364 */ ··· 1158 1149 1159 1150 struct page *follow_page(struct vm_area_struct *vma, unsigned long address, 1160 1151 unsigned int foll_flags) 1161 - { 1162 - return NULL; 1163 - } 1164 - 1165 - struct vm_area_struct *find_extend_vma(struct mm_struct *mm, unsigned long addr) 1166 1152 { 1167 1153 return NULL; 1168 1154 }