diff options
author | Pauli Nieminen <suokkos@gmail.com> | 2010-04-01 08:45:03 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2010-04-05 21:36:18 -0400 |
commit | c96af79e3463d5d3f865625baa8bb8aa4c0944a0 (patch) | |
tree | d3ed3dd9a4a9e8beda500f51213bd0c7e5c28884 | |
parent | 975efdb1bf925ad48d4e3fe5339a85f12601e10d (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.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/ttm/ttm_page_alloc.c | 113 | ||||
-rw-r--r-- | include/drm/ttm/ttm_page_alloc.h | 2 |
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; |
398 | out_no_zone: | 398 | out_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 | |||
75 | struct ttm_pool_opts { | 81 | struct 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 | **/ |
96 | struct ttm_pool_manager { | 102 | struct 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 | ||
119 | static struct attribute ttm_page_pool_max = { | ||
120 | .name = "pool_max_size", | ||
121 | .mode = S_IRUGO | S_IWUSR | ||
122 | }; | ||
123 | static struct attribute ttm_page_pool_small = { | ||
124 | .name = "pool_small_allocation", | ||
125 | .mode = S_IRUGO | S_IWUSR | ||
126 | }; | ||
127 | static struct attribute ttm_page_pool_alloc_size = { | ||
128 | .name = "pool_allocation_size", | ||
129 | .mode = S_IRUGO | S_IWUSR | ||
130 | }; | ||
131 | |||
132 | static 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 | |||
139 | static 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 | |||
146 | static 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 | |||
183 | static 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 | |||
202 | static const struct sysfs_ops ttm_pool_sysfs_ops = { | ||
203 | .show = &ttm_pool_show, | ||
204 | .store = &ttm_pool_store, | ||
205 | }; | ||
206 | |||
207 | static 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 | |||
112 | static struct ttm_pool_manager _manager = { | 213 | static 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 | ||
672 | int ttm_page_alloc_init(unsigned max_pages) | 773 | int 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 | ||
712 | int ttm_page_alloc_debugfs(struct seq_file *m, void *data) | 823 | int 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 | */ |
64 | int ttm_page_alloc_init(unsigned max_pages); | 64 | int ttm_page_alloc_init(struct ttm_mem_global *glob, unsigned max_pages); |
65 | /** | 65 | /** |
66 | * Free pool allocator. | 66 | * Free pool allocator. |
67 | */ | 67 | */ |