hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/kernel/trace/ftrace.c
....@@ -1091,7 +1091,7 @@
10911091 struct ftrace_page *next;
10921092 struct dyn_ftrace *records;
10931093 int index;
1094
- int size;
1094
+ int order;
10951095 };
10961096
10971097 #define ENTRY_SIZE sizeof(struct dyn_ftrace)
....@@ -1538,7 +1538,8 @@
15381538 key.flags = end; /* overload flags, as it is unsigned long */
15391539
15401540 for (pg = ftrace_pages_start; pg; pg = pg->next) {
1541
- if (end < pg->records[0].ip ||
1541
+ if (pg->index == 0 ||
1542
+ end < pg->records[0].ip ||
15421543 start >= (pg->records[pg->index - 1].ip + MCOUNT_INSN_SIZE))
15431544 continue;
15441545 rec = bsearch(&key, pg->records, pg->index,
....@@ -3187,7 +3188,7 @@
31873188 ftrace_number_of_groups++;
31883189
31893190 cnt = (PAGE_SIZE << order) / ENTRY_SIZE;
3190
- pg->size = cnt;
3191
+ pg->order = order;
31913192
31923193 if (cnt > count)
31933194 cnt = count;
....@@ -3195,12 +3196,27 @@
31953196 return cnt;
31963197 }
31973198
3199
+static void ftrace_free_pages(struct ftrace_page *pages)
3200
+{
3201
+ struct ftrace_page *pg = pages;
3202
+
3203
+ while (pg) {
3204
+ if (pg->records) {
3205
+ free_pages((unsigned long)pg->records, pg->order);
3206
+ ftrace_number_of_pages -= 1 << pg->order;
3207
+ }
3208
+ pages = pg->next;
3209
+ kfree(pg);
3210
+ pg = pages;
3211
+ ftrace_number_of_groups--;
3212
+ }
3213
+}
3214
+
31983215 static struct ftrace_page *
31993216 ftrace_allocate_pages(unsigned long num_to_init)
32003217 {
32013218 struct ftrace_page *start_pg;
32023219 struct ftrace_page *pg;
3203
- int order;
32043220 int cnt;
32053221
32063222 if (!num_to_init)
....@@ -3234,17 +3250,7 @@
32343250 return start_pg;
32353251
32363252 free_pages:
3237
- pg = start_pg;
3238
- while (pg) {
3239
- order = get_count_order(pg->size / ENTRIES_PER_PAGE);
3240
- if (order >= 0)
3241
- free_pages((unsigned long)pg->records, order);
3242
- start_pg = pg->next;
3243
- kfree(pg);
3244
- pg = start_pg;
3245
- ftrace_number_of_pages -= 1 << order;
3246
- ftrace_number_of_groups--;
3247
- }
3253
+ ftrace_free_pages(start_pg);
32483254 pr_info("ftrace: FAILED to allocate memory for functions\n");
32493255 return NULL;
32503256 }
....@@ -5389,12 +5395,15 @@
53895395 ret = 0;
53905396 }
53915397
5392
- if (unlikely(ret && new_direct)) {
5393
- direct->count++;
5394
- list_del_rcu(&new_direct->next);
5395
- synchronize_rcu_tasks();
5396
- kfree(new_direct);
5397
- ftrace_direct_func_count--;
5398
+ if (ret) {
5399
+ direct->addr = old_addr;
5400
+ if (unlikely(new_direct)) {
5401
+ direct->count++;
5402
+ list_del_rcu(&new_direct->next);
5403
+ synchronize_rcu_tasks();
5404
+ kfree(new_direct);
5405
+ ftrace_direct_func_count--;
5406
+ }
53985407 }
53995408
54005409 out_unlock:
....@@ -6187,9 +6196,11 @@
61876196 unsigned long *start,
61886197 unsigned long *end)
61896198 {
6199
+ struct ftrace_page *pg_unuse = NULL;
61906200 struct ftrace_page *start_pg;
61916201 struct ftrace_page *pg;
61926202 struct dyn_ftrace *rec;
6203
+ unsigned long skipped = 0;
61936204 unsigned long count;
61946205 unsigned long *p;
61956206 unsigned long addr;
....@@ -6235,6 +6246,7 @@
62356246 p = start;
62366247 pg = start_pg;
62376248 while (p < end) {
6249
+ unsigned long end_offset;
62386250 addr = ftrace_call_adjust(*p++);
62396251 /*
62406252 * Some architecture linkers will pad between
....@@ -6242,10 +6254,13 @@
62426254 * object files to satisfy alignments.
62436255 * Skip any NULL pointers.
62446256 */
6245
- if (!addr)
6257
+ if (!addr) {
6258
+ skipped++;
62466259 continue;
6260
+ }
62476261
6248
- if (pg->index == pg->size) {
6262
+ end_offset = (pg->index+1) * sizeof(pg->records[0]);
6263
+ if (end_offset > PAGE_SIZE << pg->order) {
62496264 /* We should have allocated enough */
62506265 if (WARN_ON(!pg->next))
62516266 break;
....@@ -6256,8 +6271,10 @@
62566271 rec->ip = addr;
62576272 }
62586273
6259
- /* We should have used all pages */
6260
- WARN_ON(pg->next);
6274
+ if (pg->next) {
6275
+ pg_unuse = pg->next;
6276
+ pg->next = NULL;
6277
+ }
62616278
62626279 /* Assign the last page to ftrace_pages */
62636280 ftrace_pages = pg;
....@@ -6279,6 +6296,11 @@
62796296 out:
62806297 mutex_unlock(&ftrace_lock);
62816298
6299
+ /* We should have used all pages unless we skipped some */
6300
+ if (pg_unuse) {
6301
+ WARN_ON(!skipped);
6302
+ ftrace_free_pages(pg_unuse);
6303
+ }
62826304 return ret;
62836305 }
62846306
....@@ -6414,7 +6436,6 @@
64146436 struct ftrace_page **last_pg;
64156437 struct ftrace_page *tmp_page = NULL;
64166438 struct ftrace_page *pg;
6417
- int order;
64186439
64196440 mutex_lock(&ftrace_lock);
64206441
....@@ -6465,12 +6486,12 @@
64656486 /* Needs to be called outside of ftrace_lock */
64666487 clear_mod_from_hashes(pg);
64676488
6468
- order = get_count_order(pg->size / ENTRIES_PER_PAGE);
6469
- if (order >= 0)
6470
- free_pages((unsigned long)pg->records, order);
6489
+ if (pg->records) {
6490
+ free_pages((unsigned long)pg->records, pg->order);
6491
+ ftrace_number_of_pages -= 1 << pg->order;
6492
+ }
64716493 tmp_page = pg->next;
64726494 kfree(pg);
6473
- ftrace_number_of_pages -= 1 << order;
64746495 ftrace_number_of_groups--;
64756496 }
64766497 }
....@@ -6788,7 +6809,6 @@
67886809 struct ftrace_mod_map *mod_map = NULL;
67896810 struct ftrace_init_func *func, *func_next;
67906811 struct list_head clear_hash;
6791
- int order;
67926812
67936813 INIT_LIST_HEAD(&clear_hash);
67946814
....@@ -6826,10 +6846,10 @@
68266846 ftrace_update_tot_cnt--;
68276847 if (!pg->index) {
68286848 *last_pg = pg->next;
6829
- order = get_count_order(pg->size / ENTRIES_PER_PAGE);
6830
- if (order >= 0)
6831
- free_pages((unsigned long)pg->records, order);
6832
- ftrace_number_of_pages -= 1 << order;
6849
+ if (pg->records) {
6850
+ free_pages((unsigned long)pg->records, pg->order);
6851
+ ftrace_number_of_pages -= 1 << pg->order;
6852
+ }
68336853 ftrace_number_of_groups--;
68346854 kfree(pg);
68356855 pg = container_of(last_pg, struct ftrace_page, next);