summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/common
diff options
context:
space:
mode:
authorDeepak Nibade <dnibade@nvidia.com>2017-04-17 02:55:48 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2017-04-18 04:15:13 -0400
commit07b15f68c7e4a58df70992e7b314263ea48bffc3 (patch)
tree456a5e8818f84912d0c7cbd720b4c1aae618d543 /drivers/gpu/nvgpu/common
parente65893db0c4a8e9918c2d78af755d74906d43409 (diff)
gpu: nvgpu: use nvgpu rbtree for kmem allocator
Use nvgpu rbtree instead of linux rbtree for kmem allocator Move to use nvgpu_rbtree_node structure and nvgpu_rbtree_* APIs Jira NVGPU-13 Change-Id: I3403f93bc32fd1b05f35c46ee6a77e9375b62a2f Signed-off-by: Deepak Nibade <dnibade@nvidia.com> Reviewed-on: http://git-master/r/1457860 Reviewed-by: svccoveritychecker <svccoveritychecker@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/common')
-rw-r--r--drivers/gpu/nvgpu/common/linux/kmem.c104
-rw-r--r--drivers/gpu/nvgpu/common/linux/kmem_priv.h14
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,
73static int nvgpu_add_alloc(struct nvgpu_mem_alloc_tracker *tracker, 72static 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
101static struct nvgpu_mem_alloc *nvgpu_rem_alloc( 82static 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)
690static void do_nvgpu_kmem_cleanup(struct nvgpu_mem_alloc_tracker *tracker, 659static 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
67static inline struct nvgpu_mem_alloc *
68nvgpu_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 {
71struct nvgpu_mem_alloc_tracker { 77struct 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;