|
23 | 23 | #include <linux/mutex.h> |
24 | 24 | #include <linux/percpu.h> |
25 | 25 | #include <linux/printk.h> |
| 26 | +#include <linux/refcount.h> |
26 | 27 | #include <linux/slab.h> |
27 | 28 | #include <linux/spinlock.h> |
28 | 29 | #include <linux/stacktrace.h> |
@@ -60,6 +61,7 @@ struct stack_record { |
60 | 61 | u32 hash; /* Hash in hash table */ |
61 | 62 | u32 size; /* Number of stored frames */ |
62 | 63 | union handle_parts handle; |
| 64 | + refcount_t count; |
63 | 65 | unsigned long entries[CONFIG_STACKDEPOT_MAX_FRAMES]; /* Frames */ |
64 | 66 | }; |
65 | 67 |
|
@@ -373,6 +375,7 @@ depot_alloc_stack(unsigned long *entries, int size, u32 hash, void **prealloc) |
373 | 375 | stack->hash = hash; |
374 | 376 | stack->size = size; |
375 | 377 | /* stack->handle is already filled in by depot_init_pool(). */ |
| 378 | + refcount_set(&stack->count, 1); |
376 | 379 | memcpy(stack->entries, entries, flex_array_size(stack, entries, size)); |
377 | 380 |
|
378 | 381 | /* |
@@ -489,6 +492,8 @@ depot_stack_handle_t stack_depot_save_flags(unsigned long *entries, |
489 | 492 | /* Fast path: look the stack trace up without full locking. */ |
490 | 493 | found = find_stack(bucket, entries, nr_entries, hash); |
491 | 494 | if (found) { |
| 495 | + if (depot_flags & STACK_DEPOT_FLAG_GET) |
| 496 | + refcount_inc(&found->count); |
492 | 497 | read_unlock_irqrestore(&pool_rwlock, flags); |
493 | 498 | goto exit; |
494 | 499 | } |
@@ -528,12 +533,15 @@ depot_stack_handle_t stack_depot_save_flags(unsigned long *entries, |
528 | 533 | list_add(&new->list, bucket); |
529 | 534 | found = new; |
530 | 535 | } |
531 | | - } else if (prealloc) { |
| 536 | + } else { |
| 537 | + if (depot_flags & STACK_DEPOT_FLAG_GET) |
| 538 | + refcount_inc(&found->count); |
532 | 539 | /* |
533 | 540 | * Stack depot already contains this stack trace, but let's |
534 | 541 | * keep the preallocated memory for future. |
535 | 542 | */ |
536 | | - depot_keep_new_pool(&prealloc); |
| 543 | + if (prealloc) |
| 544 | + depot_keep_new_pool(&prealloc); |
537 | 545 | } |
538 | 546 |
|
539 | 547 | write_unlock_irqrestore(&pool_rwlock, flags); |
|
0 commit comments