Skip to content

Commit 044d2ae

Browse files
surenbaghdasaryanakpm00
authored andcommitted
alloc_tag: handle module codetag load errors as module load failures
Failures inside codetag_load_module() are currently ignored. As a result an error there would not cause a module load failure and freeing of the associated resources. Correct this behavior by propagating the error code to the caller and handling possible errors. With this change, error to allocate percpu counters, which happens at this stage, will not be ignored and will cause a module load failure and freeing of resources. With this change we also do not need to disable memory allocation profiling when this error happens, instead we fail to load the module. Link: https://lkml.kernel.org/r/[email protected] Fixes: 1007526 ("alloc_tag: allocate percpu counters for module tags dynamically") Signed-off-by: Suren Baghdasaryan <[email protected]> Reported-by: Casey Chen <[email protected]> Closes: https://lore.kernel.org/all/[email protected]/ Cc: Daniel Gomez <[email protected]> Cc: David Wang <[email protected]> Cc: Kent Overstreet <[email protected]> Cc: Luis Chamberalin <[email protected]> Cc: Petr Pavlu <[email protected]> Cc: Sami Tolvanen <[email protected]> Cc: <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent 9c49e5d commit 044d2ae

File tree

4 files changed

+39
-20
lines changed

4 files changed

+39
-20
lines changed

include/linux/codetag.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ union codetag_ref {
3636
struct codetag_type_desc {
3737
const char *section;
3838
size_t tag_size;
39-
void (*module_load)(struct module *mod,
40-
struct codetag *start, struct codetag *end);
39+
int (*module_load)(struct module *mod,
40+
struct codetag *start, struct codetag *end);
4141
void (*module_unload)(struct module *mod,
4242
struct codetag *start, struct codetag *end);
4343
#ifdef CONFIG_MODULES
@@ -89,7 +89,7 @@ void *codetag_alloc_module_section(struct module *mod, const char *name,
8989
unsigned long align);
9090
void codetag_free_module_sections(struct module *mod);
9191
void codetag_module_replaced(struct module *mod, struct module *new_mod);
92-
void codetag_load_module(struct module *mod);
92+
int codetag_load_module(struct module *mod);
9393
void codetag_unload_module(struct module *mod);
9494

9595
#else /* defined(CONFIG_CODE_TAGGING) && defined(CONFIG_MODULES) */
@@ -103,7 +103,7 @@ codetag_alloc_module_section(struct module *mod, const char *name,
103103
unsigned long align) { return NULL; }
104104
static inline void codetag_free_module_sections(struct module *mod) {}
105105
static inline void codetag_module_replaced(struct module *mod, struct module *new_mod) {}
106-
static inline void codetag_load_module(struct module *mod) {}
106+
static inline int codetag_load_module(struct module *mod) { return 0; }
107107
static inline void codetag_unload_module(struct module *mod) {}
108108

109109
#endif /* defined(CONFIG_CODE_TAGGING) && defined(CONFIG_MODULES) */

kernel/module/main.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3386,11 +3386,12 @@ static int load_module(struct load_info *info, const char __user *uargs,
33863386
goto sysfs_cleanup;
33873387
}
33883388

3389+
if (codetag_load_module(mod))
3390+
goto sysfs_cleanup;
3391+
33893392
/* Get rid of temporary copy. */
33903393
free_copy(info, flags);
33913394

3392-
codetag_load_module(mod);
3393-
33943395
/* Done! */
33953396
trace_module_load(mod);
33963397

lib/alloc_tag.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -607,15 +607,16 @@ static void release_module_tags(struct module *mod, bool used)
607607
mas_unlock(&mas);
608608
}
609609

610-
static void load_module(struct module *mod, struct codetag *start, struct codetag *stop)
610+
static int load_module(struct module *mod, struct codetag *start, struct codetag *stop)
611611
{
612612
/* Allocate module alloc_tag percpu counters */
613613
struct alloc_tag *start_tag;
614614
struct alloc_tag *stop_tag;
615615
struct alloc_tag *tag;
616616

617+
/* percpu counters for core allocations are already statically allocated */
617618
if (!mod)
618-
return;
619+
return 0;
619620

620621
start_tag = ct_to_alloc_tag(start);
621622
stop_tag = ct_to_alloc_tag(stop);
@@ -627,12 +628,13 @@ static void load_module(struct module *mod, struct codetag *start, struct codeta
627628
free_percpu(tag->counters);
628629
tag->counters = NULL;
629630
}
630-
shutdown_mem_profiling(true);
631-
pr_err("Failed to allocate memory for allocation tag percpu counters in the module %s. Memory allocation profiling is disabled!\n",
631+
pr_err("Failed to allocate memory for allocation tag percpu counters in the module %s\n",
632632
mod->name);
633-
break;
633+
return -ENOMEM;
634634
}
635635
}
636+
637+
return 0;
636638
}
637639

638640
static void replace_module(struct module *mod, struct module *new_mod)

lib/codetag.c

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ static int codetag_module_init(struct codetag_type *cttype, struct module *mod)
167167
{
168168
struct codetag_range range;
169169
struct codetag_module *cmod;
170+
int mod_id;
170171
int err;
171172

172173
range = get_section_range(mod, cttype->desc.section);
@@ -190,11 +191,20 @@ static int codetag_module_init(struct codetag_type *cttype, struct module *mod)
190191
cmod->range = range;
191192

192193
down_write(&cttype->mod_lock);
193-
err = idr_alloc(&cttype->mod_idr, cmod, 0, 0, GFP_KERNEL);
194-
if (err >= 0) {
195-
cttype->count += range_size(cttype, &range);
196-
if (cttype->desc.module_load)
197-
cttype->desc.module_load(mod, range.start, range.stop);
194+
mod_id = idr_alloc(&cttype->mod_idr, cmod, 0, 0, GFP_KERNEL);
195+
if (mod_id >= 0) {
196+
if (cttype->desc.module_load) {
197+
err = cttype->desc.module_load(mod, range.start, range.stop);
198+
if (!err)
199+
cttype->count += range_size(cttype, &range);
200+
else
201+
idr_remove(&cttype->mod_idr, mod_id);
202+
} else {
203+
cttype->count += range_size(cttype, &range);
204+
err = 0;
205+
}
206+
} else {
207+
err = mod_id;
198208
}
199209
up_write(&cttype->mod_lock);
200210

@@ -295,17 +305,23 @@ void codetag_module_replaced(struct module *mod, struct module *new_mod)
295305
mutex_unlock(&codetag_lock);
296306
}
297307

298-
void codetag_load_module(struct module *mod)
308+
int codetag_load_module(struct module *mod)
299309
{
300310
struct codetag_type *cttype;
311+
int ret = 0;
301312

302313
if (!mod)
303-
return;
314+
return 0;
304315

305316
mutex_lock(&codetag_lock);
306-
list_for_each_entry(cttype, &codetag_types, link)
307-
codetag_module_init(cttype, mod);
317+
list_for_each_entry(cttype, &codetag_types, link) {
318+
ret = codetag_module_init(cttype, mod);
319+
if (ret)
320+
break;
321+
}
308322
mutex_unlock(&codetag_lock);
323+
324+
return ret;
309325
}
310326

311327
void codetag_unload_module(struct module *mod)

0 commit comments

Comments
 (0)