aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPauli Nieminen <suokkos@gmail.com>2010-04-01 08:45:03 -0400
committerDave Airlie <airlied@redhat.com>2010-04-05 21:36:18 -0400
commitc96af79e3463d5d3f865625baa8bb8aa4c0944a0 (patch)
treed3ed3dd9a4a9e8beda500f51213bd0c7e5c28884
parent975efdb1bf925ad48d4e3fe5339a85f12601e10d (diff)
drm/ttm: Add sysfs interface to control pool allocator.
Sysfs interface allows user to configure pool allocator functionality and change limits for the size of pool. Signed-off-by: Pauli Nieminen <suokkos@gmail.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
-rw-r--r--drivers/gpu/drm/ttm/ttm_memory.c2
-rw-r--r--drivers/gpu/drm/ttm/ttm_page_alloc.c113
-rw-r--r--include/drm/ttm/ttm_page_alloc.h2
3 files changed, 114 insertions, 3 deletions
diff --git a/drivers/gpu/drm/ttm/ttm_memory.c b/drivers/gpu/drm/ttm/ttm_memory.c
index daff8a87977e..5e3f177323cb 100644
--- a/drivers/gpu/drm/ttm/ttm_memory.c
+++ b/drivers/gpu/drm/ttm/ttm_memory.c
@@ -393,7 +393,7 @@ int ttm_mem_global_init(struct ttm_mem_global *glob)
393 "Zone %7s: Available graphics memory: %llu kiB.\n", 393 "Zone %7s: Available graphics memory: %llu kiB.\n",
394 zone->name, (unsigned long long) zone->max_mem >> 10); 394 zone->name, (unsigned long long) zone->max_mem >> 10);
395 } 395 }
396 ttm_page_alloc_init(glob->zone_kernel->max_mem/(2*PAGE_SIZE)); 396 ttm_page_alloc_init(glob, glob->zone_kernel->max_mem/(2*PAGE_SIZE));
397 return 0; 397 return 0;
398out_no_zone: 398out_no_zone:
399 ttm_mem_global_release(glob); 399 ttm_mem_global_release(glob);
diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc.c b/drivers/gpu/drm/ttm/ttm_page_alloc.c
index 57799dba35e0..6ca9b27e33d5 100644
--- a/drivers/gpu/drm/ttm/ttm_page_alloc.c
+++ b/drivers/gpu/drm/ttm/ttm_page_alloc.c
@@ -72,6 +72,12 @@ struct ttm_page_pool {
72 unsigned long nrefills; 72 unsigned long nrefills;
73}; 73};
74 74
75/**
76 * Limits for the pool. They are handled without locks because only place where
77 * they may change is in sysfs store. They won't have immediate effect anyway
78 * so forcing serialiazation to access them is pointless.
79 */
80
75struct ttm_pool_opts { 81struct ttm_pool_opts {
76 unsigned alloc_size; 82 unsigned alloc_size;
77 unsigned max_size; 83 unsigned max_size;
@@ -94,6 +100,7 @@ struct ttm_pool_opts {
94 * @pools: All pool objects in use. 100 * @pools: All pool objects in use.
95 **/ 101 **/
96struct ttm_pool_manager { 102struct ttm_pool_manager {
103 struct kobject kobj;
97 struct shrinker mm_shrink; 104 struct shrinker mm_shrink;
98 atomic_t page_alloc_inited; 105 atomic_t page_alloc_inited;
99 struct ttm_pool_opts options; 106 struct ttm_pool_opts options;
@@ -109,6 +116,100 @@ struct ttm_pool_manager {
109 }; 116 };
110}; 117};
111 118
119static struct attribute ttm_page_pool_max = {
120 .name = "pool_max_size",
121 .mode = S_IRUGO | S_IWUSR
122};
123static struct attribute ttm_page_pool_small = {
124 .name = "pool_small_allocation",
125 .mode = S_IRUGO | S_IWUSR
126};
127static struct attribute ttm_page_pool_alloc_size = {
128 .name = "pool_allocation_size",
129 .mode = S_IRUGO | S_IWUSR
130};
131
132static struct attribute *ttm_pool_attrs[] = {
133 &ttm_page_pool_max,
134 &ttm_page_pool_small,
135 &ttm_page_pool_alloc_size,
136 NULL
137};
138
139static void ttm_pool_kobj_release(struct kobject *kobj)
140{
141 struct ttm_pool_manager *m =
142 container_of(kobj, struct ttm_pool_manager, kobj);
143 (void)m;
144}
145
146static ssize_t ttm_pool_store(struct kobject *kobj,
147 struct attribute *attr, const char *buffer, size_t size)
148{
149 struct ttm_pool_manager *m =
150 container_of(kobj, struct ttm_pool_manager, kobj);
151 int chars;
152 unsigned val;
153 chars = sscanf(buffer, "%u", &val);
154 if (chars == 0)
155 return size;
156
157 /* Convert kb to number of pages */
158 val = val / (PAGE_SIZE >> 10);
159
160 if (attr == &ttm_page_pool_max)
161 m->options.max_size = val;
162 else if (attr == &ttm_page_pool_small)
163 m->options.small = val;
164 else if (attr == &ttm_page_pool_alloc_size) {
165 if (val > NUM_PAGES_TO_ALLOC*8) {
166 printk(KERN_ERR "[ttm] Setting allocation size to %lu "
167 "is not allowed. Recomended size is "
168 "%lu\n",
169 NUM_PAGES_TO_ALLOC*(PAGE_SIZE >> 7),
170 NUM_PAGES_TO_ALLOC*(PAGE_SIZE >> 10));
171 return size;
172 } else if (val > NUM_PAGES_TO_ALLOC) {
173 printk(KERN_WARNING "[ttm] Setting allocation size to "
174 "larger than %lu is not recomended.\n",
175 NUM_PAGES_TO_ALLOC*(PAGE_SIZE >> 10));
176 }
177 m->options.alloc_size = val;
178 }
179
180 return size;
181}
182
183static ssize_t ttm_pool_show(struct kobject *kobj,
184 struct attribute *attr, char *buffer)
185{
186 struct ttm_pool_manager *m =
187 container_of(kobj, struct ttm_pool_manager, kobj);
188 unsigned val = 0;
189
190 if (attr == &ttm_page_pool_max)
191 val = m->options.max_size;
192 else if (attr == &ttm_page_pool_small)
193 val = m->options.small;
194 else if (attr == &ttm_page_pool_alloc_size)
195 val = m->options.alloc_size;
196
197 val = val * (PAGE_SIZE >> 10);
198
199 return snprintf(buffer, PAGE_SIZE, "%u\n", val);
200}
201
202static const struct sysfs_ops ttm_pool_sysfs_ops = {
203 .show = &ttm_pool_show,
204 .store = &ttm_pool_store,
205};
206
207static struct kobj_type ttm_pool_kobj_type = {
208 .release = &ttm_pool_kobj_release,
209 .sysfs_ops = &ttm_pool_sysfs_ops,
210 .default_attrs = ttm_pool_attrs,
211};
212
112static struct ttm_pool_manager _manager = { 213static struct ttm_pool_manager _manager = {
113 .page_alloc_inited = ATOMIC_INIT(0) 214 .page_alloc_inited = ATOMIC_INIT(0)
114}; 215};
@@ -669,8 +770,9 @@ static void ttm_page_pool_init_locked(struct ttm_page_pool *pool, int flags,
669 pool->name = name; 770 pool->name = name;
670} 771}
671 772
672int ttm_page_alloc_init(unsigned max_pages) 773int ttm_page_alloc_init(struct ttm_mem_global *glob, unsigned max_pages)
673{ 774{
775 int ret;
674 if (atomic_add_return(1, &_manager.page_alloc_inited) > 1) 776 if (atomic_add_return(1, &_manager.page_alloc_inited) > 1)
675 return 0; 777 return 0;
676 778
@@ -690,6 +792,13 @@ int ttm_page_alloc_init(unsigned max_pages)
690 _manager.options.small = SMALL_ALLOCATION; 792 _manager.options.small = SMALL_ALLOCATION;
691 _manager.options.alloc_size = NUM_PAGES_TO_ALLOC; 793 _manager.options.alloc_size = NUM_PAGES_TO_ALLOC;
692 794
795 kobject_init(&_manager.kobj, &ttm_pool_kobj_type);
796 ret = kobject_add(&_manager.kobj, &glob->kobj, "pool");
797 if (unlikely(ret != 0)) {
798 kobject_put(&_manager.kobj);
799 return ret;
800 }
801
693 ttm_pool_mm_shrink_init(&_manager); 802 ttm_pool_mm_shrink_init(&_manager);
694 803
695 return 0; 804 return 0;
@@ -707,6 +816,8 @@ void ttm_page_alloc_fini()
707 816
708 for (i = 0; i < NUM_POOLS; ++i) 817 for (i = 0; i < NUM_POOLS; ++i)
709 ttm_page_pool_free(&_manager.pools[i], FREE_ALL_PAGES); 818 ttm_page_pool_free(&_manager.pools[i], FREE_ALL_PAGES);
819
820 kobject_put(&_manager.kobj);
710} 821}
711 822
712int ttm_page_alloc_debugfs(struct seq_file *m, void *data) 823int ttm_page_alloc_debugfs(struct seq_file *m, void *data)
diff --git a/include/drm/ttm/ttm_page_alloc.h b/include/drm/ttm/ttm_page_alloc.h
index 8b091c309df4..8bb4de567b2c 100644
--- a/include/drm/ttm/ttm_page_alloc.h
+++ b/include/drm/ttm/ttm_page_alloc.h
@@ -61,7 +61,7 @@ void ttm_put_pages(struct list_head *pages,
61 * multiple times but ttm_page_alloc_fini has to be called same number of 61 * multiple times but ttm_page_alloc_fini has to be called same number of
62 * times. 62 * times.
63 */ 63 */
64int ttm_page_alloc_init(unsigned max_pages); 64int ttm_page_alloc_init(struct ttm_mem_global *glob, unsigned max_pages);
65/** 65/**
66 * Free pool allocator. 66 * Free pool allocator.
67 */ 67 */