Hi Linus,
As Al suggested:
Alexander Viro wrote:
> If anything, fs/nls/nls_base.c may be more worth it - same problem, same
> solution, same chance to use rwlocks and potentially longer list to deal
> with.
so I had a look and indeed it was in principle the same situation as with
file_systems but it was more worth it with file_systems because there are
explicit ways to traverse the list (sysfs(2) and /proc/filesystems) by
user action whilst for nls it seems we only traverse the list if we want
to load_nls() which means we would usually load a module and modify the
list and thus take a write lock. I.e. load_nls() would be:
find_nls() - take a read nls_lock
request_module() - take a write nls_lock in register_nls()
find_nls() - take a read nls_lock
So, the only saving is ability to execute 1st and 3rd parts of that code
concurrently but the middle is still serialized because of
register_nls() taking nls_lock for write.
Nevertheless, I promoted nls_lock from being a plain spinlock to being a
rw spinlock - better a little improvement than none at all.
Regards,
Tigran
--- fs/nls/nls_base.c.0 Wed May 3 10:55:05 2000
+++ fs/nls/nls_base.c Wed May 3 10:57:41 2000
@@ -21,7 +21,7 @@
#include <asm/byteorder.h>
static struct nls_table *tables = (struct nls_table *) NULL;
-static spinlock_t nls_lock = SPIN_LOCK_UNLOCKED;
+static rwlock_t nls_lock = RW_LOCK_UNLOCKED;
/*
* Sample implementation from Unicode home page.
@@ -168,17 +168,17 @@
if (nls->next)
return -EBUSY;
- spin_lock(&nls_lock);
+ write_lock(&nls_lock);
while (*tmp) {
if (nls == *tmp) {
- spin_unlock(&nls_lock);
+ write_unlock(&nls_lock);
return -EBUSY;
}
tmp = &(*tmp)->next;
}
nls->next = tables;
tables = nls;
- spin_unlock(&nls_lock);
+ write_unlock(&nls_lock);
return 0;
}
@@ -186,29 +186,29 @@
{
struct nls_table ** tmp = &tables;
- spin_lock(&nls_lock);
+ write_lock(&nls_lock);
while (*tmp) {
if (nls == *tmp) {
*tmp = nls->next;
- spin_unlock(&nls_lock);
+ write_unlock(&nls_lock);
return 0;
}
tmp = &(*tmp)->next;
}
- spin_unlock(&nls_lock);
+ write_unlock(&nls_lock);
return -EINVAL;
}
static struct nls_table *find_nls(char *charset)
{
struct nls_table *nls;
- spin_lock(&nls_lock);
+ read_lock(&nls_lock);
for (nls = tables; nls; nls = nls->next)
if (! strcmp(nls->charset, charset))
break;
if (nls && !try_inc_mod_count(nls->owner))
nls = NULL;
- spin_unlock(&nls_lock);
+ read_unlock(&nls_lock);
return nls;
}
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/
This archive was generated by hypermail 2b29 : Sun May 07 2000 - 21:00:11 EST