diff options
| author | Eric Anholt <eric@anholt.net> | 2009-11-21 21:49:37 -0500 |
|---|---|---|
| committer | Eric Anholt <eric@anholt.net> | 2009-11-25 09:36:21 -0500 |
| commit | c8e0f93a381d1d76135e567f13a4418fce66fd95 (patch) | |
| tree | efa286f2e381d60b514c897cd148e5a824cce667 /include | |
| parent | 5b8f0be0dce012d190a53d55240fe3fde6306476 (diff) | |
drm/i915: Replace a calloc followed by copying data over it with malloc.
Execbufs involve quite a bit of payload, to the extent that cache misses
show up in the profiles here, and a suspicion that some of those cachelines
may get evicted and then reloaded in the subsequent copy.
This is still abstracted like drm_calloc_large since we want to check for
size overflow, and because we want to choose between kmalloc and vmalloc
on the fly. cairo's interface for malloc-with-calloc's-args was used as
the model.
Signed-off-by: Eric Anholt <eric@anholt.net>
Diffstat (limited to 'include')
| -rw-r--r-- | include/drm/drmP.h | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/include/drm/drmP.h b/include/drm/drmP.h index b0b36838ab11..1b807d0f6cdb 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h | |||
| @@ -1545,14 +1545,27 @@ static __inline__ void drm_core_dropmap(struct drm_local_map *map) | |||
| 1545 | 1545 | ||
| 1546 | static __inline__ void *drm_calloc_large(size_t nmemb, size_t size) | 1546 | static __inline__ void *drm_calloc_large(size_t nmemb, size_t size) |
| 1547 | { | 1547 | { |
| 1548 | if (size != 0 && nmemb > ULONG_MAX / size) | ||
| 1549 | return NULL; | ||
| 1550 | |||
| 1548 | if (size * nmemb <= PAGE_SIZE) | 1551 | if (size * nmemb <= PAGE_SIZE) |
| 1549 | return kcalloc(nmemb, size, GFP_KERNEL); | 1552 | return kcalloc(nmemb, size, GFP_KERNEL); |
| 1550 | 1553 | ||
| 1554 | return __vmalloc(size * nmemb, | ||
| 1555 | GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, PAGE_KERNEL); | ||
| 1556 | } | ||
| 1557 | |||
| 1558 | /* Modeled after cairo's malloc_ab, it's like calloc but without the zeroing. */ | ||
| 1559 | static __inline__ void *drm_malloc_ab(size_t nmemb, size_t size) | ||
| 1560 | { | ||
| 1551 | if (size != 0 && nmemb > ULONG_MAX / size) | 1561 | if (size != 0 && nmemb > ULONG_MAX / size) |
| 1552 | return NULL; | 1562 | return NULL; |
| 1553 | 1563 | ||
| 1564 | if (size * nmemb <= PAGE_SIZE) | ||
| 1565 | return kmalloc(nmemb * size, GFP_KERNEL); | ||
| 1566 | |||
| 1554 | return __vmalloc(size * nmemb, | 1567 | return __vmalloc(size * nmemb, |
| 1555 | GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, PAGE_KERNEL); | 1568 | GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL); |
| 1556 | } | 1569 | } |
| 1557 | 1570 | ||
| 1558 | static __inline void drm_free_large(void *ptr) | 1571 | static __inline void drm_free_large(void *ptr) |
