diff options
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/nvgpu/common/linux/kmem.c | 104 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/common/linux/kmem_priv.h | 14 |
2 files changed, 48 insertions, 70 deletions
diff --git a/drivers/gpu/nvgpu/common/linux/kmem.c b/drivers/gpu/nvgpu/common/linux/kmem.c index 819b3a11..4fe68830 100644 --- a/drivers/gpu/nvgpu/common/linux/kmem.c +++ b/drivers/gpu/nvgpu/common/linux/kmem.c | |||
@@ -16,7 +16,6 @@ | |||
16 | 16 | ||
17 | #include <linux/mutex.h> | 17 | #include <linux/mutex.h> |
18 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
19 | #include <linux/rbtree.h> | ||
20 | #include <linux/debugfs.h> | 19 | #include <linux/debugfs.h> |
21 | #include <linux/spinlock.h> | 20 | #include <linux/spinlock.h> |
22 | #include <linux/seq_file.h> | 21 | #include <linux/seq_file.h> |
@@ -73,53 +72,26 @@ static void kmem_print_mem_alloc(struct gk20a *g, | |||
73 | static int nvgpu_add_alloc(struct nvgpu_mem_alloc_tracker *tracker, | 72 | static int nvgpu_add_alloc(struct nvgpu_mem_alloc_tracker *tracker, |
74 | struct nvgpu_mem_alloc *alloc) | 73 | struct nvgpu_mem_alloc *alloc) |
75 | { | 74 | { |
76 | struct rb_node **new = &tracker->allocs.rb_node; | 75 | alloc->allocs_entry.key_start = alloc->addr; |
77 | struct rb_node *parent = NULL; | 76 | alloc->allocs_entry.key_end = alloc->addr + alloc->size; |
78 | |||
79 | while (*new) { | ||
80 | struct nvgpu_mem_alloc *tmp = rb_entry(*new, | ||
81 | struct nvgpu_mem_alloc, | ||
82 | allocs_entry); | ||
83 | |||
84 | parent = *new; | ||
85 | |||
86 | if (alloc->addr < tmp->addr) | ||
87 | new = &(*new)->rb_left; | ||
88 | else if (alloc->addr > tmp->addr) | ||
89 | new = &(*new)->rb_right; | ||
90 | else | ||
91 | return -EINVAL; | ||
92 | } | ||
93 | |||
94 | /* Put the new node there */ | ||
95 | rb_link_node(&alloc->allocs_entry, parent, new); | ||
96 | rb_insert_color(&alloc->allocs_entry, &tracker->allocs); | ||
97 | 77 | ||
78 | nvgpu_rbtree_insert(&alloc->allocs_entry, &tracker->allocs); | ||
98 | return 0; | 79 | return 0; |
99 | } | 80 | } |
100 | 81 | ||
101 | static struct nvgpu_mem_alloc *nvgpu_rem_alloc( | 82 | static struct nvgpu_mem_alloc *nvgpu_rem_alloc( |
102 | struct nvgpu_mem_alloc_tracker *tracker, u64 alloc_addr) | 83 | struct nvgpu_mem_alloc_tracker *tracker, u64 alloc_addr) |
103 | { | 84 | { |
104 | struct rb_node *node = tracker->allocs.rb_node; | ||
105 | struct nvgpu_mem_alloc *alloc; | 85 | struct nvgpu_mem_alloc *alloc; |
86 | struct nvgpu_rbtree_node *node = NULL; | ||
106 | 87 | ||
107 | while (node) { | 88 | nvgpu_rbtree_search(alloc_addr, &node, tracker->allocs); |
108 | alloc = container_of(node, | ||
109 | struct nvgpu_mem_alloc, allocs_entry); | ||
110 | |||
111 | if (alloc_addr < alloc->addr) | ||
112 | node = node->rb_left; | ||
113 | else if (alloc_addr > alloc->addr) | ||
114 | node = node->rb_right; | ||
115 | else | ||
116 | break; | ||
117 | } | ||
118 | |||
119 | if (!node) | 89 | if (!node) |
120 | return NULL; | 90 | return NULL; |
121 | 91 | ||
122 | rb_erase(node, &tracker->allocs); | 92 | alloc = nvgpu_mem_alloc_from_rbtree_node(node); |
93 | |||
94 | nvgpu_rbtree_unlink(node, &tracker->allocs); | ||
123 | 95 | ||
124 | return alloc; | 96 | return alloc; |
125 | } | 97 | } |
@@ -417,7 +389,7 @@ static void print_histogram(struct nvgpu_mem_alloc_tracker *tracker, | |||
417 | u64 nr_buckets; | 389 | u64 nr_buckets; |
418 | unsigned int *buckets; | 390 | unsigned int *buckets; |
419 | unsigned int total_allocs; | 391 | unsigned int total_allocs; |
420 | struct rb_node *node; | 392 | struct nvgpu_rbtree_node *node; |
421 | static const char histogram_line[] = | 393 | static const char histogram_line[] = |
422 | "++++++++++++++++++++++++++++++++++++++++"; | 394 | "++++++++++++++++++++++++++++++++++++++++"; |
423 | 395 | ||
@@ -443,15 +415,13 @@ static void print_histogram(struct nvgpu_mem_alloc_tracker *tracker, | |||
443 | * should go in. Round the size down to the nearest power of two to | 415 | * should go in. Round the size down to the nearest power of two to |
444 | * find the right bucket. | 416 | * find the right bucket. |
445 | */ | 417 | */ |
446 | for (node = rb_first(&tracker->allocs); | 418 | nvgpu_rbtree_enum_start(0, &node, tracker->allocs); |
447 | node != NULL; | 419 | while (node) { |
448 | node = rb_next(node)) { | ||
449 | int b; | 420 | int b; |
450 | u64 bucket_min; | 421 | u64 bucket_min; |
451 | struct nvgpu_mem_alloc *alloc; | 422 | struct nvgpu_mem_alloc *alloc = |
423 | nvgpu_mem_alloc_from_rbtree_node(node); | ||
452 | 424 | ||
453 | alloc = container_of(node, struct nvgpu_mem_alloc, | ||
454 | allocs_entry); | ||
455 | bucket_min = (u64)rounddown_pow_of_two(alloc->size); | 425 | bucket_min = (u64)rounddown_pow_of_two(alloc->size); |
456 | if (bucket_min < tracker->min_alloc) | 426 | if (bucket_min < tracker->min_alloc) |
457 | bucket_min = tracker->min_alloc; | 427 | bucket_min = tracker->min_alloc; |
@@ -469,6 +439,8 @@ static void print_histogram(struct nvgpu_mem_alloc_tracker *tracker, | |||
469 | b--; | 439 | b--; |
470 | 440 | ||
471 | buckets[b]++; | 441 | buckets[b]++; |
442 | |||
443 | nvgpu_rbtree_enum_next(&node, node); | ||
472 | } | 444 | } |
473 | 445 | ||
474 | total_allocs = 0; | 446 | total_allocs = 0; |
@@ -569,17 +541,16 @@ static int __kmem_traces_dump_tracker(struct gk20a *g, | |||
569 | struct nvgpu_mem_alloc_tracker *tracker, | 541 | struct nvgpu_mem_alloc_tracker *tracker, |
570 | struct seq_file *s) | 542 | struct seq_file *s) |
571 | { | 543 | { |
572 | struct rb_node *node; | 544 | struct nvgpu_rbtree_node *node; |
573 | |||
574 | for (node = rb_first(&tracker->allocs); | ||
575 | node != NULL; | ||
576 | node = rb_next(node)) { | ||
577 | struct nvgpu_mem_alloc *alloc; | ||
578 | 545 | ||
579 | alloc = container_of(node, struct nvgpu_mem_alloc, | 546 | nvgpu_rbtree_enum_start(0, &node, tracker->allocs); |
580 | allocs_entry); | 547 | while (node) { |
548 | struct nvgpu_mem_alloc *alloc = | ||
549 | nvgpu_mem_alloc_from_rbtree_node(node); | ||
581 | 550 | ||
582 | kmem_print_mem_alloc(g, alloc, s); | 551 | kmem_print_mem_alloc(g, alloc, s); |
552 | |||
553 | nvgpu_rbtree_enum_next(&node, node); | ||
583 | } | 554 | } |
584 | 555 | ||
585 | return 0; | 556 | return 0; |
@@ -647,21 +618,19 @@ static int __do_check_for_outstanding_allocs( | |||
647 | struct nvgpu_mem_alloc_tracker *tracker, | 618 | struct nvgpu_mem_alloc_tracker *tracker, |
648 | const char *type, bool silent) | 619 | const char *type, bool silent) |
649 | { | 620 | { |
650 | struct rb_node *node; | 621 | struct nvgpu_rbtree_node *node; |
651 | int count = 0; | 622 | int count = 0; |
652 | 623 | ||
653 | for (node = rb_first(&tracker->allocs); | 624 | nvgpu_rbtree_enum_start(0, &node, tracker->allocs); |
654 | node != NULL; | 625 | while (node) { |
655 | node = rb_next(node)) { | 626 | struct nvgpu_mem_alloc *alloc = |
656 | struct nvgpu_mem_alloc *alloc; | 627 | nvgpu_mem_alloc_from_rbtree_node(node); |
657 | |||
658 | alloc = container_of(node, struct nvgpu_mem_alloc, | ||
659 | allocs_entry); | ||
660 | 628 | ||
661 | if (!silent) | 629 | if (!silent) |
662 | kmem_print_mem_alloc(g, alloc, NULL); | 630 | kmem_print_mem_alloc(g, alloc, NULL); |
663 | 631 | ||
664 | count++; | 632 | count++; |
633 | nvgpu_rbtree_enum_next(&node, node); | ||
665 | } | 634 | } |
666 | 635 | ||
667 | return count; | 636 | return count; |
@@ -690,17 +659,20 @@ static int check_for_outstanding_allocs(struct gk20a *g, bool silent) | |||
690 | static void do_nvgpu_kmem_cleanup(struct nvgpu_mem_alloc_tracker *tracker, | 659 | static void do_nvgpu_kmem_cleanup(struct nvgpu_mem_alloc_tracker *tracker, |
691 | void (*force_free_func)(const void *)) | 660 | void (*force_free_func)(const void *)) |
692 | { | 661 | { |
693 | struct rb_node *node; | 662 | struct nvgpu_rbtree_node *node; |
694 | 663 | ||
695 | while ((node = rb_first(&tracker->allocs)) != NULL) { | 664 | nvgpu_rbtree_enum_start(0, &node, tracker->allocs); |
696 | struct nvgpu_mem_alloc *alloc; | 665 | while (node) { |
666 | struct nvgpu_mem_alloc *alloc = | ||
667 | nvgpu_mem_alloc_from_rbtree_node(node); | ||
697 | 668 | ||
698 | alloc = container_of(node, struct nvgpu_mem_alloc, | ||
699 | allocs_entry); | ||
700 | if (force_free_func) | 669 | if (force_free_func) |
701 | force_free_func((void *)alloc->addr); | 670 | force_free_func((void *)alloc->addr); |
702 | 671 | ||
672 | nvgpu_rbtree_unlink(node, &tracker->allocs); | ||
703 | kfree(alloc); | 673 | kfree(alloc); |
674 | |||
675 | nvgpu_rbtree_enum_start(0, &node, tracker->allocs); | ||
704 | } | 676 | } |
705 | } | 677 | } |
706 | 678 | ||
@@ -772,8 +744,8 @@ int nvgpu_kmem_init(struct gk20a *g) | |||
772 | g->vmallocs->name = "vmalloc"; | 744 | g->vmallocs->name = "vmalloc"; |
773 | g->kmallocs->name = "kmalloc"; | 745 | g->kmallocs->name = "kmalloc"; |
774 | 746 | ||
775 | g->vmallocs->allocs = RB_ROOT; | 747 | g->vmallocs->allocs = NULL; |
776 | g->kmallocs->allocs = RB_ROOT; | 748 | g->kmallocs->allocs = NULL; |
777 | 749 | ||
778 | mutex_init(&g->vmallocs->lock); | 750 | mutex_init(&g->vmallocs->lock); |
779 | mutex_init(&g->kmallocs->lock); | 751 | mutex_init(&g->kmallocs->lock); |
diff --git a/drivers/gpu/nvgpu/common/linux/kmem_priv.h b/drivers/gpu/nvgpu/common/linux/kmem_priv.h index 5e38ad5d..cd58ac28 100644 --- a/drivers/gpu/nvgpu/common/linux/kmem_priv.h +++ b/drivers/gpu/nvgpu/common/linux/kmem_priv.h | |||
@@ -17,7 +17,7 @@ | |||
17 | #ifndef __KMEM_PRIV_H__ | 17 | #ifndef __KMEM_PRIV_H__ |
18 | #define __KMEM_PRIV_H__ | 18 | #define __KMEM_PRIV_H__ |
19 | 19 | ||
20 | #include <linux/rbtree.h> | 20 | #include <nvgpu/rbtree.h> |
21 | 21 | ||
22 | #define __pstat(s, fmt, msg...) \ | 22 | #define __pstat(s, fmt, msg...) \ |
23 | do { \ | 23 | do { \ |
@@ -61,8 +61,14 @@ struct nvgpu_mem_alloc { | |||
61 | unsigned long size; | 61 | unsigned long size; |
62 | unsigned long real_size; | 62 | unsigned long real_size; |
63 | 63 | ||
64 | /* Ugh - linux specific. Will need to be abstracted. */ | 64 | struct nvgpu_rbtree_node allocs_entry; |
65 | struct rb_node allocs_entry; | 65 | }; |
66 | |||
67 | static inline struct nvgpu_mem_alloc * | ||
68 | nvgpu_mem_alloc_from_rbtree_node(struct nvgpu_rbtree_node *node) | ||
69 | { | ||
70 | return (struct nvgpu_mem_alloc *) | ||
71 | ((uintptr_t)node - offsetof(struct nvgpu_mem_alloc, allocs_entry)); | ||
66 | }; | 72 | }; |
67 | 73 | ||
68 | /* | 74 | /* |
@@ -71,7 +77,7 @@ struct nvgpu_mem_alloc { | |||
71 | struct nvgpu_mem_alloc_tracker { | 77 | struct nvgpu_mem_alloc_tracker { |
72 | const char *name; | 78 | const char *name; |
73 | struct nvgpu_kmem_cache *allocs_cache; | 79 | struct nvgpu_kmem_cache *allocs_cache; |
74 | struct rb_root allocs; | 80 | struct nvgpu_rbtree_node *allocs; |
75 | struct mutex lock; | 81 | struct mutex lock; |
76 | 82 | ||
77 | u64 bytes_alloced; | 83 | u64 bytes_alloced; |