mirror of
https://github.com/Fishwaldo/linux-bl808.git
synced 2025-06-17 20:25:19 +00:00
module: struct module_ref should contains long fields
module_ref contains two "unsigned int" fields.
Thats now too small, since some machines can open more than 2^32 files.
Check commit 518de9b39e
(fs: allow for more than 2^31 files) for
reference.
We can add an aligned(2 * sizeof(unsigned long)) attribute to force
alloc_percpu() allocating module_ref areas in single cache lines.
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
CC: Rusty Russell <rusty@rustcorp.com.au>
CC: Tejun Heo <tj@kernel.org>
CC: Robin Holt <holt@sgi.com>
CC: David Miller <davem@davemloft.net>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
48fd11880b
commit
bd77c04772
3 changed files with 21 additions and 10 deletions
|
@ -205,6 +205,20 @@ enum module_state
|
||||||
MODULE_STATE_GOING,
|
MODULE_STATE_GOING,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct module_ref - per cpu module reference counts
|
||||||
|
* @incs: number of module get on this cpu
|
||||||
|
* @decs: number of module put on this cpu
|
||||||
|
*
|
||||||
|
* We force an alignment on 8 or 16 bytes, so that alloc_percpu()
|
||||||
|
* put @incs/@decs in same cache line, with no extra memory cost,
|
||||||
|
* since alloc_percpu() is fine grained.
|
||||||
|
*/
|
||||||
|
struct module_ref {
|
||||||
|
unsigned long incs;
|
||||||
|
unsigned long decs;
|
||||||
|
} __attribute((aligned(2 * sizeof(unsigned long))));
|
||||||
|
|
||||||
struct module
|
struct module
|
||||||
{
|
{
|
||||||
enum module_state state;
|
enum module_state state;
|
||||||
|
@ -347,10 +361,7 @@ struct module
|
||||||
/* Destruction function. */
|
/* Destruction function. */
|
||||||
void (*exit)(void);
|
void (*exit)(void);
|
||||||
|
|
||||||
struct module_ref {
|
struct module_ref __percpu *refptr;
|
||||||
unsigned int incs;
|
|
||||||
unsigned int decs;
|
|
||||||
} __percpu *refptr;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_CONSTRUCTORS
|
#ifdef CONFIG_CONSTRUCTORS
|
||||||
|
@ -434,7 +445,7 @@ extern void __module_put_and_exit(struct module *mod, long code)
|
||||||
#define module_put_and_exit(code) __module_put_and_exit(THIS_MODULE, code);
|
#define module_put_and_exit(code) __module_put_and_exit(THIS_MODULE, code);
|
||||||
|
|
||||||
#ifdef CONFIG_MODULE_UNLOAD
|
#ifdef CONFIG_MODULE_UNLOAD
|
||||||
unsigned int module_refcount(struct module *mod);
|
unsigned long module_refcount(struct module *mod);
|
||||||
void __symbol_put(const char *symbol);
|
void __symbol_put(const char *symbol);
|
||||||
#define symbol_put(x) __symbol_put(MODULE_SYMBOL_PREFIX #x)
|
#define symbol_put(x) __symbol_put(MODULE_SYMBOL_PREFIX #x)
|
||||||
void symbol_put_addr(void *addr);
|
void symbol_put_addr(void *addr);
|
||||||
|
|
|
@ -1982,7 +1982,7 @@ static int kdb_lsmod(int argc, const char **argv)
|
||||||
kdb_printf("%-20s%8u 0x%p ", mod->name,
|
kdb_printf("%-20s%8u 0x%p ", mod->name,
|
||||||
mod->core_size, (void *)mod);
|
mod->core_size, (void *)mod);
|
||||||
#ifdef CONFIG_MODULE_UNLOAD
|
#ifdef CONFIG_MODULE_UNLOAD
|
||||||
kdb_printf("%4d ", module_refcount(mod));
|
kdb_printf("%4ld ", module_refcount(mod));
|
||||||
#endif
|
#endif
|
||||||
if (mod->state == MODULE_STATE_GOING)
|
if (mod->state == MODULE_STATE_GOING)
|
||||||
kdb_printf(" (Unloading)");
|
kdb_printf(" (Unloading)");
|
||||||
|
|
|
@ -725,9 +725,9 @@ static int try_stop_module(struct module *mod, int flags, int *forced)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int module_refcount(struct module *mod)
|
unsigned long module_refcount(struct module *mod)
|
||||||
{
|
{
|
||||||
unsigned int incs = 0, decs = 0;
|
unsigned long incs = 0, decs = 0;
|
||||||
int cpu;
|
int cpu;
|
||||||
|
|
||||||
for_each_possible_cpu(cpu)
|
for_each_possible_cpu(cpu)
|
||||||
|
@ -853,7 +853,7 @@ static inline void print_unload_info(struct seq_file *m, struct module *mod)
|
||||||
struct module_use *use;
|
struct module_use *use;
|
||||||
int printed_something = 0;
|
int printed_something = 0;
|
||||||
|
|
||||||
seq_printf(m, " %u ", module_refcount(mod));
|
seq_printf(m, " %lu ", module_refcount(mod));
|
||||||
|
|
||||||
/* Always include a trailing , so userspace can differentiate
|
/* Always include a trailing , so userspace can differentiate
|
||||||
between this and the old multi-field proc format. */
|
between this and the old multi-field proc format. */
|
||||||
|
@ -903,7 +903,7 @@ EXPORT_SYMBOL_GPL(symbol_put_addr);
|
||||||
static ssize_t show_refcnt(struct module_attribute *mattr,
|
static ssize_t show_refcnt(struct module_attribute *mattr,
|
||||||
struct module_kobject *mk, char *buffer)
|
struct module_kobject *mk, char *buffer)
|
||||||
{
|
{
|
||||||
return sprintf(buffer, "%u\n", module_refcount(mk->mod));
|
return sprintf(buffer, "%lu\n", module_refcount(mk->mod));
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct module_attribute refcnt = {
|
static struct module_attribute refcnt = {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue