* [patch 5/5] vfs: use kmalloc() to allocate fdmem if possible
@ 2010-05-24 19:24 akpm
0 siblings, 0 replies; 2+ messages in thread
From: akpm @ 2010-05-24 19:24 UTC (permalink / raw)
To: viro
Cc: linux-fsdevel, akpm, xiaosuo, adobriyan, avi, jslaby, mingo,
paulmck, penguin-kernel, peterz
From: Changli Gao <xiaosuo@gmail.com>
Use kmalloc() to allocate fdmem if possible.
vmalloc() is used as a fallback solution for fdmem allocation. A new
helper function __free_fdtable() is introduced to reduce the lines of
code.
A potential bug, vfree() a memory allocated by kmalloc(), is fixed.
[akpm@linux-foundation.org: use __GFP_NOWARN, uninline alloc_fdmem() and free_fdmem()]
Signed-off-by: Changli Gao <xiaosuo@gmail.com>
Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Jiri Slaby <jslaby@suse.cz>
Cc: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
Cc: Alexey Dobriyan <adobriyan@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Avi Kivity <avi@redhat.com>
Cc: Tetsuo Handa <penguin-kernel@i-love.sakura.ne.jp>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---
fs/file.c | 57 ++++++++++++++++++++--------------------------------
1 file changed, 23 insertions(+), 34 deletions(-)
diff -puN fs/file.c~vfs-use-kmalloc-to-allocate-fdmem-if-possible fs/file.c
--- a/fs/file.c~vfs-use-kmalloc-to-allocate-fdmem-if-possible
+++ a/fs/file.c
@@ -39,28 +39,27 @@ int sysctl_nr_open_max = 1024 * 1024; /*
*/
static DEFINE_PER_CPU(struct fdtable_defer, fdtable_defer_list);
-static inline void * alloc_fdmem(unsigned int size)
+static inline void *alloc_fdmem(unsigned int size)
{
- if (size <= PAGE_SIZE)
- return kmalloc(size, GFP_KERNEL);
- else
- return vmalloc(size);
+ void *data;
+
+ data = kmalloc(size, GFP_KERNEL|__GFP_NOWARN);
+ if (data != NULL)
+ return data;
+
+ return vmalloc(size);
}
-static inline void free_fdarr(struct fdtable *fdt)
+static void free_fdmem(void *ptr)
{
- if (fdt->max_fds <= (PAGE_SIZE / sizeof(struct file *)))
- kfree(fdt->fd);
- else
- vfree(fdt->fd);
+ is_vmalloc_addr(ptr) ? vfree(ptr) : kfree(ptr);
}
-static inline void free_fdset(struct fdtable *fdt)
+static void __free_fdtable(struct fdtable *fdt)
{
- if (fdt->max_fds <= (PAGE_SIZE * BITS_PER_BYTE / 2))
- kfree(fdt->open_fds);
- else
- vfree(fdt->open_fds);
+ free_fdmem(fdt->fd);
+ free_fdmem(fdt->open_fds);
+ kfree(fdt);
}
static void free_fdtable_work(struct work_struct *work)
@@ -75,9 +74,8 @@ static void free_fdtable_work(struct wor
spin_unlock_bh(&f->lock);
while(fdt) {
struct fdtable *next = fdt->next;
- vfree(fdt->fd);
- free_fdset(fdt);
- kfree(fdt);
+
+ __free_fdtable(fdt);
fdt = next;
}
}
@@ -98,7 +96,7 @@ void free_fdtable_rcu(struct rcu_head *r
container_of(fdt, struct files_struct, fdtab));
return;
}
- if (fdt->max_fds <= (PAGE_SIZE / sizeof(struct file *))) {
+ if (!is_vmalloc_addr(fdt->fd) && !is_vmalloc_addr(fdt->open_fds)) {
kfree(fdt->fd);
kfree(fdt->open_fds);
kfree(fdt);
@@ -184,7 +182,7 @@ static struct fdtable * alloc_fdtable(un
return fdt;
out_arr:
- free_fdarr(fdt);
+ free_fdmem(fdt->fd);
out_fdt:
kfree(fdt);
out:
@@ -214,9 +212,7 @@ static int expand_fdtable(struct files_s
* caller and alloc_fdtable(). Cheaper to catch it here...
*/
if (unlikely(new_fdt->max_fds <= nr)) {
- free_fdarr(new_fdt);
- free_fdset(new_fdt);
- kfree(new_fdt);
+ __free_fdtable(new_fdt);
return -EMFILE;
}
/*
@@ -232,9 +228,7 @@ static int expand_fdtable(struct files_s
free_fdtable(cur_fdt);
} else {
/* Somebody else expanded, so undo our attempt */
- free_fdarr(new_fdt);
- free_fdset(new_fdt);
- kfree(new_fdt);
+ __free_fdtable(new_fdt);
}
return 1;
}
@@ -325,11 +319,8 @@ struct files_struct *dup_fd(struct files
while (unlikely(open_files > new_fdt->max_fds)) {
spin_unlock(&oldf->file_lock);
- if (new_fdt != &newf->fdtab) {
- free_fdarr(new_fdt);
- free_fdset(new_fdt);
- kfree(new_fdt);
- }
+ if (new_fdt != &newf->fdtab)
+ __free_fdtable(new_fdt);
new_fdt = alloc_fdtable(open_files - 1);
if (!new_fdt) {
@@ -339,9 +330,7 @@ struct files_struct *dup_fd(struct files
/* beyond sysctl_nr_open; nothing to do */
if (unlikely(new_fdt->max_fds < open_files)) {
- free_fdarr(new_fdt);
- free_fdset(new_fdt);
- kfree(new_fdt);
+ __free_fdtable(new_fdt);
*errorp = -EMFILE;
goto out_release;
}
_
^ permalink raw reply [flat|nested] 2+ messages in thread
* [patch 5/5] vfs: use kmalloc() to allocate fdmem if possible
@ 2010-07-20 22:29 akpm
0 siblings, 0 replies; 2+ messages in thread
From: akpm @ 2010-07-20 22:29 UTC (permalink / raw)
To: viro
Cc: linux-fsdevel, akpm, xiaosuo, adobriyan, avi, jslaby, mingo,
paulmck, penguin-kernel, peterz
From: Changli Gao <xiaosuo@gmail.com>
Use kmalloc() to allocate fdmem if possible.
vmalloc() is used as a fallback solution for fdmem allocation. A new
helper function __free_fdtable() is introduced to reduce the lines of
code.
A potential bug, vfree() a memory allocated by kmalloc(), is fixed.
[akpm@linux-foundation.org: use __GFP_NOWARN, uninline alloc_fdmem() and free_fdmem()]
Signed-off-by: Changli Gao <xiaosuo@gmail.com>
Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Jiri Slaby <jslaby@suse.cz>
Cc: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
Cc: Alexey Dobriyan <adobriyan@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Avi Kivity <avi@redhat.com>
Cc: Tetsuo Handa <penguin-kernel@i-love.sakura.ne.jp>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---
fs/file.c | 57 ++++++++++++++++++++--------------------------------
1 file changed, 23 insertions(+), 34 deletions(-)
diff -puN fs/file.c~vfs-use-kmalloc-to-allocate-fdmem-if-possible fs/file.c
--- a/fs/file.c~vfs-use-kmalloc-to-allocate-fdmem-if-possible
+++ a/fs/file.c
@@ -39,28 +39,27 @@ int sysctl_nr_open_max = 1024 * 1024; /*
*/
static DEFINE_PER_CPU(struct fdtable_defer, fdtable_defer_list);
-static inline void * alloc_fdmem(unsigned int size)
+static inline void *alloc_fdmem(unsigned int size)
{
- if (size <= PAGE_SIZE)
- return kmalloc(size, GFP_KERNEL);
- else
- return vmalloc(size);
+ void *data;
+
+ data = kmalloc(size, GFP_KERNEL|__GFP_NOWARN);
+ if (data != NULL)
+ return data;
+
+ return vmalloc(size);
}
-static inline void free_fdarr(struct fdtable *fdt)
+static void free_fdmem(void *ptr)
{
- if (fdt->max_fds <= (PAGE_SIZE / sizeof(struct file *)))
- kfree(fdt->fd);
- else
- vfree(fdt->fd);
+ is_vmalloc_addr(ptr) ? vfree(ptr) : kfree(ptr);
}
-static inline void free_fdset(struct fdtable *fdt)
+static void __free_fdtable(struct fdtable *fdt)
{
- if (fdt->max_fds <= (PAGE_SIZE * BITS_PER_BYTE / 2))
- kfree(fdt->open_fds);
- else
- vfree(fdt->open_fds);
+ free_fdmem(fdt->fd);
+ free_fdmem(fdt->open_fds);
+ kfree(fdt);
}
static void free_fdtable_work(struct work_struct *work)
@@ -75,9 +74,8 @@ static void free_fdtable_work(struct wor
spin_unlock_bh(&f->lock);
while(fdt) {
struct fdtable *next = fdt->next;
- vfree(fdt->fd);
- free_fdset(fdt);
- kfree(fdt);
+
+ __free_fdtable(fdt);
fdt = next;
}
}
@@ -98,7 +96,7 @@ void free_fdtable_rcu(struct rcu_head *r
container_of(fdt, struct files_struct, fdtab));
return;
}
- if (fdt->max_fds <= (PAGE_SIZE / sizeof(struct file *))) {
+ if (!is_vmalloc_addr(fdt->fd) && !is_vmalloc_addr(fdt->open_fds)) {
kfree(fdt->fd);
kfree(fdt->open_fds);
kfree(fdt);
@@ -183,7 +181,7 @@ static struct fdtable * alloc_fdtable(un
return fdt;
out_arr:
- free_fdarr(fdt);
+ free_fdmem(fdt->fd);
out_fdt:
kfree(fdt);
out:
@@ -213,9 +211,7 @@ static int expand_fdtable(struct files_s
* caller and alloc_fdtable(). Cheaper to catch it here...
*/
if (unlikely(new_fdt->max_fds <= nr)) {
- free_fdarr(new_fdt);
- free_fdset(new_fdt);
- kfree(new_fdt);
+ __free_fdtable(new_fdt);
return -EMFILE;
}
/*
@@ -231,9 +227,7 @@ static int expand_fdtable(struct files_s
free_fdtable(cur_fdt);
} else {
/* Somebody else expanded, so undo our attempt */
- free_fdarr(new_fdt);
- free_fdset(new_fdt);
- kfree(new_fdt);
+ __free_fdtable(new_fdt);
}
return 1;
}
@@ -323,11 +317,8 @@ struct files_struct *dup_fd(struct files
while (unlikely(open_files > new_fdt->max_fds)) {
spin_unlock(&oldf->file_lock);
- if (new_fdt != &newf->fdtab) {
- free_fdarr(new_fdt);
- free_fdset(new_fdt);
- kfree(new_fdt);
- }
+ if (new_fdt != &newf->fdtab)
+ __free_fdtable(new_fdt);
new_fdt = alloc_fdtable(open_files - 1);
if (!new_fdt) {
@@ -337,9 +328,7 @@ struct files_struct *dup_fd(struct files
/* beyond sysctl_nr_open; nothing to do */
if (unlikely(new_fdt->max_fds < open_files)) {
- free_fdarr(new_fdt);
- free_fdset(new_fdt);
- kfree(new_fdt);
+ __free_fdtable(new_fdt);
*errorp = -EMFILE;
goto out_release;
}
_
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2010-07-20 22:30 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-05-24 19:24 [patch 5/5] vfs: use kmalloc() to allocate fdmem if possible akpm
-- strict thread matches above, loose matches on Subject: below --
2010-07-20 22:29 akpm
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).