Messages in this thread Patch in this message | | | Date | Wed, 12 May 1999 16:50:22 -0300 (EST) | From | Marcelo Tosatti <> | Subject | [PATCH][2.3.0] Read-write locks instead semaphores on UTS structures |
| |
This patch implements read-write locks instead semaphores in UTS structures as noted by Linus in kernel/sys.c.
Linus, can you apply this?
- Marcelo diff -Nur linux.orig/CREDITS linux/CREDITS --- linux.orig/CREDITS Wed May 12 15:45:30 1999 +++ linux/CREDITS Wed May 12 15:47:32 1999 @@ -1886,6 +1886,15 @@ S: Santa Clara, California 95051 S: USA +N: Marcelo W. Tosatti +E: marcelo@conectiva.com.br +W: http://lie-br.conectiva.com.br/~marcelo/ +D: Miscellaneous kernel hacker +D: Cyclom 2X driver hacker +S: R. Prof. Rubens Elke Braga, 558 - Parolin +S: 80220-320 Curitiba - Parana +S: Brazil + N: Stefan Traby E: stefan@quant-x.com D: Minor Alpha kernel hacks diff -Nur linux.orig/arch/alpha/kernel/osf_sys.c linux/arch/alpha/kernel/osf_sys.c --- linux.orig/arch/alpha/kernel/osf_sys.c Wed May 12 15:46:58 1999 +++ linux/arch/alpha/kernel/osf_sys.c Wed May 12 15:47:33 1999 @@ -545,7 +545,7 @@ { int error; - down(&uts_sem); + read_lock(&uts_rwlock); error = -EFAULT; if (copy_to_user(name + 0, system_utsname.sysname, 32)) goto out; @@ -560,7 +560,7 @@ error = 0; out: - up(&uts_sem); + read_unlock(&uts_rwlock); return error; } @@ -619,13 +619,13 @@ if (namelen > 32) len = 32; - down(&uts_sem); + read_lock(&uts_rwlock); for (i = 0; i < len; ++i) { __put_user(system_utsname.domainname[i], name + i); if (system_utsname.domainname[i] == '\0') break; } - up(&uts_sem); + read_unlock(&uts_rwlock); out: unlock_kernel(); return error; @@ -859,7 +859,7 @@ goto out; } - down(&uts_sem); + read_lock(&uts_rwlock) res = sysinfo_table[offset]; len = strlen(res)+1; if (len > count) @@ -868,7 +868,7 @@ err = -EFAULT; else err = 0; - up(&uts_sem); + read_unlock(&uts_rwlock); out: unlock_kernel(); return err; diff -Nur linux.orig/arch/arm/kernel/sys_arm.c linux/arch/arm/kernel/sys_arm.c --- linux.orig/arch/arm/kernel/sys_arm.c Wed May 12 15:47:13 1999 +++ linux/arch/arm/kernel/sys_arm.c Wed May 12 15:47:33 1999 @@ -321,9 +321,9 @@ if(!name) return -EFAULT; - down(&uts_sem); + read_lock(&uts_rwlock); err=copy_to_user (name, &system_utsname, sizeof (*name)); - up(&uts_sem); + read_unlock(&uts_rwlock); return err?-EFAULT:0; } @@ -344,7 +344,7 @@ if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname))) return -EFAULT; - down(&uts_sem); + read_lock(&uts_rwlock); error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN); error -= __put_user(0,name->sysname+__OLD_UTS_LEN); @@ -357,7 +357,7 @@ error -= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN); error -= __put_user(0,name->machine+__OLD_UTS_LEN); - up(&uts_sem); + read_unlock(&uts_rwlock); error = error ? -EFAULT : 0; diff -Nur linux.orig/arch/i386/kernel/sys_i386.c linux/arch/i386/kernel/sys_i386.c --- linux.orig/arch/i386/kernel/sys_i386.c Wed May 12 15:46:49 1999 +++ linux/arch/i386/kernel/sys_i386.c Wed May 12 15:47:34 1999 @@ -206,9 +206,9 @@ int err; if (!name) return -EFAULT; - down(&uts_sem); + read_lock(&uts_rwlock); err=copy_to_user(name, &system_utsname, sizeof (*name)); - up(&uts_sem); + read_unlock(&uts_rwlock); return err?-EFAULT:0; } @@ -221,7 +221,7 @@ if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname))) return -EFAULT; - down(&uts_sem); + read_lock(&uts_rwlock); error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN); error |= __put_user(0,name->sysname+__OLD_UTS_LEN); @@ -234,7 +234,7 @@ error |= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN); error |= __put_user(0,name->machine+__OLD_UTS_LEN); - up(&uts_sem); + read_unlock(&uts_rwlock); error = error ? -EFAULT : 0; diff -Nur linux.orig/arch/sparc/kernel/sys_sparc.c linux/arch/sparc/kernel/sys_sparc.c --- linux.orig/arch/sparc/kernel/sys_sparc.c Wed May 12 15:47:05 1999 +++ linux/arch/sparc/kernel/sys_sparc.c Wed May 12 15:47:34 1999 @@ -344,8 +344,8 @@ int nlen; int err = -EFAULT; - down(&uts_sem); - + read_lock(&uts_rwlock); + nlen = strlen(system_utsname.domainname) + 1; if (nlen < len) @@ -356,7 +356,7 @@ goto done; err = 0; done: - up(&uts_sem); + read_unlock(&uts_rwlock); return err; } diff -Nur linux.orig/arch/sparc/kernel/sys_sunos.c linux/arch/sparc/kernel/sys_sunos.c --- linux.orig/arch/sparc/kernel/sys_sunos.c Wed May 12 15:47:06 1999 +++ linux/arch/sparc/kernel/sys_sunos.c Wed May 12 15:47:34 1999 @@ -584,7 +584,7 @@ asmlinkage int sunos_uname(struct sunos_utsname *name) { int ret; - down(&uts_sem); + read_lock(&uts_rwlock); ret = copy_to_user(&name->sname[0], &system_utsname.sysname[0], sizeof(name->sname) - 1); if (!ret) { ret |= __copy_to_user(&name->nname[0], &system_utsname.nodename[0], sizeof(name->nname) - 1); @@ -593,7 +593,7 @@ ret |= __copy_to_user(&name->ver[0], &system_utsname.version[0], sizeof(name->ver) - 1); ret |= __copy_to_user(&name->mach[0], &system_utsname.machine[0], sizeof(name->mach) - 1); } - up(&uts_sem); + read_unlock(&uts_rwlock); return ret; } diff -Nur linux.orig/arch/sparc64/kernel/sys_sparc.c linux/arch/sparc64/kernel/sys_sparc.c --- linux.orig/arch/sparc64/kernel/sys_sparc.c Wed May 12 15:47:13 1999 +++ linux/arch/sparc64/kernel/sys_sparc.c Wed May 12 15:47:34 1999 @@ -237,8 +237,8 @@ int nlen; int err = -EFAULT; - down(&uts_sem); - + read_lock(&uts_rwlock); + nlen = strlen(system_utsname.domainname) + 1; if (nlen < len) @@ -249,7 +249,7 @@ goto done; err = 0; done: - up(&uts_sem); + read_unlock(&uts_rwlock); return err; } diff -Nur linux.orig/arch/sparc64/kernel/sys_sunos32.c linux/arch/sparc64/kernel/sys_sunos32.c --- linux.orig/arch/sparc64/kernel/sys_sunos32.c Wed May 12 15:47:13 1999 +++ linux/arch/sparc64/kernel/sys_sunos32.c Wed May 12 15:47:34 1999 @@ -546,14 +546,14 @@ { int ret; - down(&uts_sem); + read_lock(&uts_rwlock); ret = copy_to_user(&name->sname[0], &system_utsname.sysname[0], sizeof(name->sname) - 1); ret |= copy_to_user(&name->nname[0], &system_utsname.nodename[0], sizeof(name->nname) - 1); ret |= put_user('\0', &name->nname[8]); ret |= copy_to_user(&name->rel[0], &system_utsname.release[0], sizeof(name->rel) - 1); ret |= copy_to_user(&name->ver[0], &system_utsname.version[0], sizeof(name->ver) - 1); ret |= copy_to_user(&name->mach[0], &system_utsname.machine[0], sizeof(name->mach) - 1); - up(&uts_sem); + read_unlock(&uts_rwlock); return ret; } diff -Nur linux.orig/arch/sparc64/solaris/misc.c linux/arch/sparc64/solaris/misc.c --- linux.orig/arch/sparc64/solaris/misc.c Wed May 12 15:47:13 1999 +++ linux/arch/sparc64/solaris/misc.c Wed May 12 15:47:34 1999 @@ -261,7 +261,7 @@ asmlinkage int solaris_utsname(u32 buf) { /* Why should we not lie a bit? */ - down(&uts_sem); + write_lock(&uts_rwlock); set_utsfield(((struct sol_utsname *)A(buf))->sysname, "SunOS", 0, 0); set_utsfield(((struct sol_utsname *)A(buf))->nodename, @@ -272,7 +272,7 @@ "Generic", 0, 0); set_utsfield(((struct sol_utsname *)A(buf))->machine, machine(), 0, 0); - up(&uts_sem); + write_unlock(&uts_rwlock); return 0; } diff -Nur linux.orig/drivers/sound/soundcard.c linux/drivers/sound/soundcard.c --- linux.orig/drivers/sound/soundcard.c Wed May 12 15:46:37 1999 +++ linux/drivers/sound/soundcard.c Wed May 12 15:47:34 1999 @@ -17,8 +17,11 @@ * which should disappear in the near future) * * Rob Riggs Added persistent DMA buffers support (1998/10/17) + * + * Marcelo Tosatti : used rw locks for reading utsname structures instead of + * semaphores */ - + #include <linux/config.h> #include "sound_config.h" @@ -163,7 +166,7 @@ #define MODULEPROCSTRING "Driver compiled into kernel" #endif - down(&uts_sem); + read_lock(&uts_rwlock); len = sprintf(buffer, "OSS/Free:" SOUND_VERSION_STRING "\n" "Load type: " MODULEPROCSTRING "\n" @@ -171,7 +174,7 @@ "Config options: %x\n\nInstalled drivers: \n", system_utsname.sysname, system_utsname.nodename, system_utsname.release, system_utsname.version, system_utsname.machine, SELECTED_SOUND_OPTIONS); - up(&uts_sem); + read_unlock(&uts_rwlock); for (i = 0; (i < num_sound_drivers) && (pos <= offset + length); i++) { if (!sound_drivers[i].card_type) diff -Nur linux.orig/include/linux/utsname.h linux/include/linux/utsname.h --- linux.orig/include/linux/utsname.h Wed May 12 15:45:30 1999 +++ linux/include/linux/utsname.h Wed May 12 15:47:34 1999 @@ -1,3 +1,5 @@ +#include <asm/spinlock.h> + #ifndef _LINUX_UTSNAME_H #define _LINUX_UTSNAME_H @@ -32,5 +34,5 @@ extern struct new_utsname system_utsname; -extern struct semaphore uts_sem; +extern rwlock_t uts_rwlock; #endif diff -Nur linux.orig/kernel/ksyms.c linux/kernel/ksyms.c --- linux.orig/kernel/ksyms.c Wed May 12 15:45:29 1999 +++ linux/kernel/ksyms.c Wed May 12 15:48:37 1999 @@ -326,8 +326,8 @@ EXPORT_SYMBOL(bdevname); EXPORT_SYMBOL(cdevname); EXPORT_SYMBOL(simple_strtoul); +EXPORT_SYMBOL(uts_rwlock); /* UTS read-write lock */ EXPORT_SYMBOL(system_utsname); /* UTS data */ -EXPORT_SYMBOL(uts_sem); /* UTS semaphore */ EXPORT_SYMBOL(sys_call_table); EXPORT_SYMBOL(machine_restart); EXPORT_SYMBOL(machine_halt); diff -Nur linux.orig/kernel/sys.c linux/kernel/sys.c --- linux.orig/kernel/sys.c Wed May 12 15:45:29 1999 +++ linux/kernel/sys.c Wed May 12 15:47:35 1999 @@ -2,6 +2,8 @@ * linux/kernel/sys.c * * Copyright (C) 1991, 1992 Linus Torvalds + * Modified: replaced uts_sem semaphore with uts_rwlock read-write lock. + * Marcelo Tosatti <marcelo@conectiva.com.br> */ #include <linux/mm.h> @@ -807,21 +809,16 @@ return 1; } -/* - * This should really be a blocking read-write lock - * rather than a semaphore. Anybody want to implement - * one? - */ -struct semaphore uts_sem = MUTEX; +rwlock_t uts_rwlock; asmlinkage int sys_newuname(struct new_utsname * name) { int errno = 0; - down(&uts_sem); + read_lock(&uts_rwlock); if (copy_to_user(name,&system_utsname,sizeof *name)) errno = -EFAULT; - up(&uts_sem); + read_unlock(&uts_rwlock); return errno; } @@ -833,13 +830,13 @@ return -EPERM; if (len < 0 || len > __NEW_UTS_LEN) return -EINVAL; - down(&uts_sem); + write_lock(&uts_rwlock); errno = -EFAULT; if (!copy_from_user(system_utsname.nodename, name, len)) { system_utsname.nodename[len] = 0; errno = 0; } - up(&uts_sem); + write_unlock(&uts_rwlock); return errno; } @@ -849,14 +846,14 @@ if (len < 0) return -EINVAL; - down(&uts_sem); + read_lock(&uts_rwlock); i = 1 + strlen(system_utsname.nodename); if (i > len) i = len; errno = 0; if (copy_to_user(name, system_utsname.nodename, i)) errno = -EFAULT; - up(&uts_sem); + read_unlock(&uts_rwlock); return errno; } @@ -873,13 +870,13 @@ if (len < 0 || len > __NEW_UTS_LEN) return -EINVAL; - down(&uts_sem); + write_lock(&uts_rwlock); errno = -EFAULT; if (!copy_from_user(system_utsname.domainname, name, len)) { errno = 0; system_utsname.domainname[len] = 0; } - up(&uts_sem); + write_unlock(&uts_rwlock); return errno; } diff -Nur linux.orig/kernel/sysctl.c linux/kernel/sysctl.c --- linux.orig/kernel/sysctl.c Wed May 12 15:45:30 1999 +++ linux/kernel/sysctl.c Wed May 12 15:47:35 1999 @@ -678,9 +678,9 @@ void *buffer, size_t *lenp) { int r; - down(&uts_sem); + write_lock(&uts_rwlock); r=proc_dostring(table,write,filp,buffer,lenp); - up(&uts_sem); + write_unlock(&uts_rwlock); return r; } | |