Instead of saving the size of the records field of the ftrace_page, store the order it uses to allocate the pages, as that is what is needed to know in order to free the pages. This simplifies the code. Link: https://lore.kernel.org/lkml/CAHk-=whyMxheOqXAORt9a7JK9gc9eHTgCJ55Pgs4p=X3RrQubQ@mail.gmail.com/
Unified · Split
| @@ -1090,7 +1090,7 @@ struct ftrace_page { · 1089 unmodified lines | ||
| 1090 | 1090 | struct ftrace_page *next; |
| 1091 | 1091 | struct dyn_ftrace *records; |
| 1092 | 1092 | int index; |
| 1093 | − int size; | |
| 1093 | + int order; | |
| 1094 | 1094 | }; |
| 1095 | 1095 | |
| 1096 | 1096 | #define ENTRY_SIZE sizeof(struct dyn_ftrace) |
| @@ -3181,7 +3181,7 @@ static int ftrace_allocate_records(struct ftrace_page *pg, int count) · 2084 unmodified lines | ||
| 3181 | 3181 | ftrace_number_of_groups++; |
| 3182 | 3182 | |
| 3183 | 3183 | cnt = (PAGE_SIZE << order) / ENTRY_SIZE; |
| 3184 | − pg->size = cnt; | |
| 3184 | + pg->order = order; | |
| 3185 | 3185 | |
| 3186 | 3186 | if (cnt > count) |
| 3187 | 3187 | cnt = count; |
| @@ -3194,7 +3194,6 @@ ftrace_allocate_pages(unsigned long num_to_init) · 6 unmodified lines | ||
| 3194 | 3194 | { |
| 3195 | 3195 | struct ftrace_page *start_pg; |
| 3196 | 3196 | struct ftrace_page *pg; |
| 3197 | − int order; | |
| 3198 | 3197 | int cnt; |
| 3199 | 3198 | |
| 3200 | 3199 | if (!num_to_init) |
| @@ -3230,13 +3229,13 @@ ftrace_allocate_pages(unsigned long num_to_init) · 29 unmodified lines | ||
| 3230 | 3229 | free_pages: |
| 3231 | 3230 | pg = start_pg; |
| 3232 | 3231 | while (pg) { |
| 3233 | − order = get_count_order(pg->size / ENTRIES_PER_PAGE); | |
| 3234 | − if (order >= 0) | |
| 3235 | − free_pages((unsigned long)pg->records, order); | |
| 3232 | + if (pg->records) { | |
| 3233 | + free_pages((unsigned long)pg->records, pg->order); | |
| 3234 | + ftrace_number_of_pages -= 1 << pg->order; | |
| 3235 | + } | |
| 3236 | 3236 | start_pg = pg->next; |
| 3237 | 3237 | kfree(pg); |
| 3238 | 3238 | pg = start_pg; |
| 3239 | − ftrace_number_of_pages -= 1 << order; | |
| 3240 | 3239 | ftrace_number_of_groups--; |
| 3241 | 3240 | } |
| 3242 | 3241 | pr_info("ftrace: FAILED to allocate memory for functions\n"); |
| @@ -6188,6 +6187,7 @@ static int ftrace_process_locs(struct module *mod, · 2945 unmodified lines | ||
| 6188 | 6187 | p = start; |
| 6189 | 6188 | pg = start_pg; |
| 6190 | 6189 | while (p < end) { |
| 6190 | + unsigned long end_offset; | |
| 6191 | 6191 | addr = ftrace_call_adjust(*p++); |
| 6192 | 6192 | /* |
| 6193 | 6193 | * Some architecture linkers will pad between |
| @@ -6198,7 +6198,8 @@ static int ftrace_process_locs(struct module *mod, · 4 unmodified lines | ||
| 6198 | 6198 | if (!addr) |
| 6199 | 6199 | continue; |
| 6200 | 6200 | |
| 6201 | − if (pg->index == pg->size) { | |
| 6201 | + end_offset = (pg->index+1) * sizeof(pg->records[0]); | |
| 6202 | + if (end_offset > PAGE_SIZE << pg->order) { | |
| 6202 | 6203 | /* We should have allocated enough */ |
| 6203 | 6204 | if (WARN_ON(!pg->next)) |
| 6204 | 6205 | break; |
| @@ -6367,7 +6368,6 @@ void ftrace_release_mod(struct module *mod) · 162 unmodified lines | ||
| 6367 | 6368 | struct ftrace_page **last_pg; |
| 6368 | 6369 | struct ftrace_page *tmp_page = NULL; |
| 6369 | 6370 | struct ftrace_page *pg; |
| 6370 | − int order; | |
| 6371 | 6371 | |
| 6372 | 6372 | mutex_lock(&ftrace_lock); |
| 6373 | 6373 | |
| @@ -6418,12 +6418,12 @@ void ftrace_release_mod(struct module *mod) · 44 unmodified lines | ||
| 6418 | 6418 | /* Needs to be called outside of ftrace_lock */ |
| 6419 | 6419 | clear_mod_from_hashes(pg); |
| 6420 | 6420 | |
| 6421 | − order = get_count_order(pg->size / ENTRIES_PER_PAGE); | |
| 6422 | − if (order >= 0) | |
| 6423 | − free_pages((unsigned long)pg->records, order); | |
| 6421 | + if (pg->records) { | |
| 6422 | + free_pages((unsigned long)pg->records, pg->order); | |
| 6423 | + ftrace_number_of_pages -= 1 << pg->order; | |
| 6424 | + } | |
| 6424 | 6425 | tmp_page = pg->next; |
| 6425 | 6426 | kfree(pg); |
| 6426 | − ftrace_number_of_pages -= 1 << order; | |
| 6427 | 6427 | ftrace_number_of_groups--; |
| 6428 | 6428 | } |
| 6429 | 6429 | } |
| @@ -6741,7 +6741,6 @@ void ftrace_free_mem(struct module *mod, void *start_ptr, void *end_ptr) · 311 unmodified lines | ||
| 6741 | 6741 | struct ftrace_mod_map *mod_map = NULL; |
| 6742 | 6742 | struct ftrace_init_func *func, *func_next; |
| 6743 | 6743 | struct list_head clear_hash; |
| 6744 | − int order; | |
| 6745 | 6744 | |
| 6746 | 6745 | INIT_LIST_HEAD(&clear_hash); |
| 6747 | 6746 | |
| @@ -6779,10 +6778,10 @@ void ftrace_free_mem(struct module *mod, void *start_ptr, void *end_ptr) · 31 unmodified lines | ||
| 6779 | 6778 | ftrace_update_tot_cnt--; |
| 6780 | 6779 | if (!pg->index) { |
| 6781 | 6780 | *last_pg = pg->next; |
| 6782 | − order = get_count_order(pg->size / ENTRIES_PER_PAGE); | |
| 6783 | − if (order >= 0) | |
| 6784 | − free_pages((unsigned long)pg->records, order); | |
| 6785 | − ftrace_number_of_pages -= 1 << order; | |
| 6781 | + if (pg->records) { | |
| 6782 | + free_pages((unsigned long)pg->records, pg->order); | |
| 6783 | + ftrace_number_of_pages -= 1 << pg->order; | |
| 6784 | + } | |
| 6786 | 6785 | ftrace_number_of_groups--; |
| 6787 | 6786 | kfree(pg); |
| 6788 | 6787 | pg = container_of(last_pg, struct ftrace_page, next); |