diff options
Diffstat (limited to 'drivers/gpu/nvgpu/common/mm/pd_cache.c')
-rw-r--r-- | drivers/gpu/nvgpu/common/mm/pd_cache.c | 40 |
1 files changed, 26 insertions, 14 deletions
diff --git a/drivers/gpu/nvgpu/common/mm/pd_cache.c b/drivers/gpu/nvgpu/common/mm/pd_cache.c index 84f45826..db48d168 100644 --- a/drivers/gpu/nvgpu/common/mm/pd_cache.c +++ b/drivers/gpu/nvgpu/common/mm/pd_cache.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. | 2 | * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. |
3 | * | 3 | * |
4 | * Permission is hereby granted, free of charge, to any person obtaining a | 4 | * Permission is hereby granted, free of charge, to any person obtaining a |
5 | * copy of this software and associated documentation files (the "Software"), | 5 | * copy of this software and associated documentation files (the "Software"), |
@@ -95,8 +95,9 @@ int nvgpu_pd_cache_init(struct gk20a *g) | |||
95 | * This gets called from finalize_poweron() so we need to make sure we | 95 | * This gets called from finalize_poweron() so we need to make sure we |
96 | * don't reinit the pd_cache over and over. | 96 | * don't reinit the pd_cache over and over. |
97 | */ | 97 | */ |
98 | if (g->mm.pd_cache) | 98 | if (g->mm.pd_cache) { |
99 | return 0; | 99 | return 0; |
100 | } | ||
100 | 101 | ||
101 | cache = nvgpu_kzalloc(g, sizeof(*cache)); | 102 | cache = nvgpu_kzalloc(g, sizeof(*cache)); |
102 | if (!cache) { | 103 | if (!cache) { |
@@ -123,8 +124,9 @@ void nvgpu_pd_cache_fini(struct gk20a *g) | |||
123 | int i; | 124 | int i; |
124 | struct nvgpu_pd_cache *cache = g->mm.pd_cache; | 125 | struct nvgpu_pd_cache *cache = g->mm.pd_cache; |
125 | 126 | ||
126 | if (!cache) | 127 | if (!cache) { |
127 | return; | 128 | return; |
129 | } | ||
128 | 130 | ||
129 | for (i = 0; i < NVGPU_PD_CACHE_COUNT; i++) { | 131 | for (i = 0; i < NVGPU_PD_CACHE_COUNT; i++) { |
130 | WARN_ON(!nvgpu_list_empty(&cache->full[i])); | 132 | WARN_ON(!nvgpu_list_empty(&cache->full[i])); |
@@ -164,8 +166,9 @@ int __nvgpu_pd_cache_alloc_direct(struct gk20a *g, | |||
164 | * going to be virtually contiguous and we don't have to force the | 166 | * going to be virtually contiguous and we don't have to force the |
165 | * underlying allocations to be physically contiguous as well. | 167 | * underlying allocations to be physically contiguous as well. |
166 | */ | 168 | */ |
167 | if (!nvgpu_iommuable(g) && bytes > PAGE_SIZE) | 169 | if (!nvgpu_iommuable(g) && bytes > PAGE_SIZE) { |
168 | flags = NVGPU_DMA_FORCE_CONTIGUOUS; | 170 | flags = NVGPU_DMA_FORCE_CONTIGUOUS; |
171 | } | ||
169 | 172 | ||
170 | err = nvgpu_dma_alloc_flags(g, flags, bytes, pd->mem); | 173 | err = nvgpu_dma_alloc_flags(g, flags, bytes, pd->mem); |
171 | if (err) { | 174 | if (err) { |
@@ -244,8 +247,9 @@ static int nvgpu_pd_cache_alloc_from_partial(struct gk20a *g, | |||
244 | mem_offs = bit_offs * pentry->pd_size; | 247 | mem_offs = bit_offs * pentry->pd_size; |
245 | 248 | ||
246 | /* Bit map full. Somethings wrong. */ | 249 | /* Bit map full. Somethings wrong. */ |
247 | if (WARN_ON(bit_offs >= ffz(pentry_mask))) | 250 | if (WARN_ON(bit_offs >= ffz(pentry_mask))) { |
248 | return -ENOMEM; | 251 | return -ENOMEM; |
252 | } | ||
249 | 253 | ||
250 | pentry->alloc_map |= 1 << bit_offs; | 254 | pentry->alloc_map |= 1 << bit_offs; |
251 | 255 | ||
@@ -281,8 +285,9 @@ static struct nvgpu_pd_mem_entry *nvgpu_pd_cache_get_partial( | |||
281 | struct nvgpu_list_node *list = | 285 | struct nvgpu_list_node *list = |
282 | &cache->partial[nvgpu_pd_cache_nr(bytes)]; | 286 | &cache->partial[nvgpu_pd_cache_nr(bytes)]; |
283 | 287 | ||
284 | if (nvgpu_list_empty(list)) | 288 | if (nvgpu_list_empty(list)) { |
285 | return NULL; | 289 | return NULL; |
290 | } | ||
286 | 291 | ||
287 | return nvgpu_list_first_entry(list, | 292 | return nvgpu_list_first_entry(list, |
288 | nvgpu_pd_mem_entry, | 293 | nvgpu_pd_mem_entry, |
@@ -308,13 +313,15 @@ static int nvgpu_pd_cache_alloc(struct gk20a *g, struct nvgpu_pd_cache *cache, | |||
308 | } | 313 | } |
309 | 314 | ||
310 | pentry = nvgpu_pd_cache_get_partial(cache, bytes); | 315 | pentry = nvgpu_pd_cache_get_partial(cache, bytes); |
311 | if (!pentry) | 316 | if (!pentry) { |
312 | err = nvgpu_pd_cache_alloc_new(g, cache, pd, bytes); | 317 | err = nvgpu_pd_cache_alloc_new(g, cache, pd, bytes); |
313 | else | 318 | } else { |
314 | err = nvgpu_pd_cache_alloc_from_partial(g, cache, pentry, pd); | 319 | err = nvgpu_pd_cache_alloc_from_partial(g, cache, pentry, pd); |
320 | } | ||
315 | 321 | ||
316 | if (err) | 322 | if (err) { |
317 | nvgpu_err(g, "PD-Alloc [C] Failed!"); | 323 | nvgpu_err(g, "PD-Alloc [C] Failed!"); |
324 | } | ||
318 | 325 | ||
319 | return err; | 326 | return err; |
320 | } | 327 | } |
@@ -335,14 +342,16 @@ int __nvgpu_pd_alloc(struct vm_gk20a *vm, struct nvgpu_gmmu_pd *pd, u32 bytes) | |||
335 | */ | 342 | */ |
336 | if (bytes >= PAGE_SIZE) { | 343 | if (bytes >= PAGE_SIZE) { |
337 | err = __nvgpu_pd_cache_alloc_direct(g, pd, bytes); | 344 | err = __nvgpu_pd_cache_alloc_direct(g, pd, bytes); |
338 | if (err) | 345 | if (err) { |
339 | return err; | 346 | return err; |
347 | } | ||
340 | 348 | ||
341 | return 0; | 349 | return 0; |
342 | } | 350 | } |
343 | 351 | ||
344 | if (WARN_ON(!g->mm.pd_cache)) | 352 | if (WARN_ON(!g->mm.pd_cache)) { |
345 | return -ENOMEM; | 353 | return -ENOMEM; |
354 | } | ||
346 | 355 | ||
347 | nvgpu_mutex_acquire(&g->mm.pd_cache->lock); | 356 | nvgpu_mutex_acquire(&g->mm.pd_cache->lock); |
348 | err = nvgpu_pd_cache_alloc(g, g->mm.pd_cache, pd, bytes); | 357 | err = nvgpu_pd_cache_alloc(g, g->mm.pd_cache, pd, bytes); |
@@ -355,8 +364,9 @@ void __nvgpu_pd_cache_free_direct(struct gk20a *g, struct nvgpu_gmmu_pd *pd) | |||
355 | { | 364 | { |
356 | pd_dbg(g, "PD-Free [D] 0x%p", pd->mem); | 365 | pd_dbg(g, "PD-Free [D] 0x%p", pd->mem); |
357 | 366 | ||
358 | if (!pd->mem) | 367 | if (!pd->mem) { |
359 | return; | 368 | return; |
369 | } | ||
360 | 370 | ||
361 | nvgpu_dma_free(g, pd->mem); | 371 | nvgpu_dma_free(g, pd->mem); |
362 | nvgpu_kfree(g, pd->mem); | 372 | nvgpu_kfree(g, pd->mem); |
@@ -407,8 +417,9 @@ static struct nvgpu_pd_mem_entry *nvgpu_pd_cache_look_up( | |||
407 | 417 | ||
408 | nvgpu_rbtree_search((u64)(uintptr_t)pd->mem, &node, | 418 | nvgpu_rbtree_search((u64)(uintptr_t)pd->mem, &node, |
409 | cache->mem_tree); | 419 | cache->mem_tree); |
410 | if (!node) | 420 | if (!node) { |
411 | return NULL; | 421 | return NULL; |
422 | } | ||
412 | 423 | ||
413 | return nvgpu_pd_mem_entry_from_tree_entry(node); | 424 | return nvgpu_pd_mem_entry_from_tree_entry(node); |
414 | } | 425 | } |
@@ -436,8 +447,9 @@ void __nvgpu_pd_free(struct vm_gk20a *vm, struct nvgpu_gmmu_pd *pd) | |||
436 | /* | 447 | /* |
437 | * Simple case: just DMA free. | 448 | * Simple case: just DMA free. |
438 | */ | 449 | */ |
439 | if (!pd->cached) | 450 | if (!pd->cached) { |
440 | return __nvgpu_pd_cache_free_direct(g, pd); | 451 | return __nvgpu_pd_cache_free_direct(g, pd); |
452 | } | ||
441 | 453 | ||
442 | nvgpu_mutex_acquire(&g->mm.pd_cache->lock); | 454 | nvgpu_mutex_acquire(&g->mm.pd_cache->lock); |
443 | nvgpu_pd_cache_free(g, g->mm.pd_cache, pd); | 455 | nvgpu_pd_cache_free(g, g->mm.pd_cache, pd); |