diff options
author | Owain Ainsworth <oga@cvs.openbsd.org> | 2008-08-28 00:19:28 +0000 |
---|---|---|
committer | Owain Ainsworth <oga@cvs.openbsd.org> | 2008-08-28 00:19:28 +0000 |
commit | 38c2548edb998c5f5ff8887c19a4477b2992bfe2 (patch) | |
tree | 4a6186dbc5300c2f85a36a39de4f5872c743e3e1 /sys/dev/pci/drm | |
parent | e85b479c756358a4afd6d9201a4848d8b07ee3cf (diff) |
replace usage of drm_memrange with extent(9). No functional change, but
should shrink the kernel somewhat. For some strange reason I was unaware
of this api when I pulled in these changes.
tested by myself and Paul de Weerd, thanks!
Diffstat (limited to 'sys/dev/pci/drm')
-rw-r--r-- | sys/dev/pci/drm/drmP.h | 45 | ||||
-rw-r--r-- | sys/dev/pci/drm/drm_bufs.c | 30 | ||||
-rw-r--r-- | sys/dev/pci/drm/drm_drv.c | 8 | ||||
-rw-r--r-- | sys/dev/pci/drm/drm_memrange.c | 270 | ||||
-rw-r--r-- | sys/dev/pci/drm/drm_vm.c | 6 | ||||
-rw-r--r-- | sys/dev/pci/drm/files.drm | 3 |
6 files changed, 27 insertions, 335 deletions
diff --git a/sys/dev/pci/drm/drmP.h b/sys/dev/pci/drm/drmP.h index bc8f3834516..83a42774a61 100644 --- a/sys/dev/pci/drm/drmP.h +++ b/sys/dev/pci/drm/drmP.h @@ -58,6 +58,7 @@ #include <sys/stdint.h> #include <sys/agpio.h> #include <sys/memrange.h> +#include <sys/extent.h> #include <sys/vnode.h> #include <uvm/uvm.h> #include <dev/pci/pcidevs.h> @@ -444,26 +445,6 @@ typedef struct drm_sg_mem { struct drm_sg_dmamem *mem; } drm_sg_mem_t; -/* - * Generic memory range manager structs - */ - -struct drm_memrange_node { - TAILQ_ENTRY(drm_memrange_node) ml_entry; - TAILQ_ENTRY(drm_memrange_node) fl_entry; - struct drm_memrange *mm; - void *private; - int free; - unsigned long start; - unsigned long size; -}; - -TAILQ_HEAD(drm_mmq, drm_memrange_node); -struct drm_memrange { - struct drm_mmq ml; - struct drm_mmq fl; -}; - typedef TAILQ_HEAD(drm_map_list, drm_local_map) drm_map_list_t; typedef struct drm_local_map { @@ -471,9 +452,9 @@ typedef struct drm_local_map { struct vga_pci_bar *bsr; /* Vga BAR, if applicable */ drm_dma_handle_t *dmah; /* Handle to DMA mem */ void *handle;/* KVA, if mapped */ - struct drm_memrange_node *mm; /* mmap offset */ bus_space_tag_t bst; /* Tag for mapped pci mem */ bus_space_handle_t bsh; /* Handle to mapped pci mem */ + u_long ext; /* extent for mmap */ drm_map_flags_t flags; /* Flags */ int mtrr; /* Boolean: MTRR used */ unsigned long offset;/* Physical address */ @@ -613,7 +594,7 @@ struct drm_device { SPLAY_HEAD(drm_magic_tree, drm_magic_entry) magiclist; /* Linked list of mappable regions. Protected by dev_lock */ - struct drm_memrange handle_mm; + struct extent *handle_ext; drm_map_list_t maplist; int max_context; @@ -842,24 +823,6 @@ drm_dma_handle_t *drm_pci_alloc(struct drm_device *, size_t, size_t, dma_addr_t); void drm_pci_free(struct drm_device *, drm_dma_handle_t *); -/* Memrange functions for managing aperture space */ -struct drm_memrange_node - *drm_memrange_get_block(struct drm_memrange_node *, - unsigned long, unsigned); -void drm_memrange_put_block(struct drm_memrange_node *); -struct drm_memrange_node - *drm_memrange_search_free(const struct drm_memrange *, - unsigned long, unsigned, int); -int drm_memrange_init(struct drm_memrange *, unsigned long, - unsigned long); -void drm_memrange_takedown(struct drm_memrange *); -int drm_memrange_clean(struct drm_memrange *); -unsigned long drm_memrange_tail_space(struct drm_memrange *); -int drm_memrange_remove_space_from_tail(struct drm_memrange *, - unsigned long); -int drm_memrange_add_space_to_tail(struct drm_memrange *, - unsigned long ); - /* Inline replacements for DRM_IOREMAP macros */ #define drm_core_ioremap_wc drm_core_ioremap static __inline__ void drm_core_ioremap(struct drm_local_map *map, struct drm_device *dev) @@ -878,7 +841,7 @@ static __inline__ struct drm_local_map *drm_core_findmap(struct drm_device *dev, DRM_SPINLOCK_ASSERT(&dev->dev_lock); TAILQ_FOREACH(map, &dev->maplist, link) { - if (offset == map->mm->start) + if (offset == map->ext) return map; } return NULL; diff --git a/sys/dev/pci/drm/drm_bufs.c b/sys/dev/pci/drm/drm_bufs.c index eb3909d9ee0..fdbf29a0f3d 100644 --- a/sys/dev/pci/drm/drm_bufs.c +++ b/sys/dev/pci/drm/drm_bufs.c @@ -113,7 +113,7 @@ drm_addmap(struct drm_device * dev, unsigned long offset, unsigned long size, drm_map_type_t type, drm_map_flags_t flags, drm_local_map_t **map_ptr) { drm_local_map_t *map; - int align; + int align, ret = 0; #if 0 /* disabled for now */ struct drm_agp_mem *entry; int valid; @@ -151,7 +151,6 @@ drm_addmap(struct drm_device * dev, unsigned long offset, unsigned long size, if (map->type == type && (map->offset == offset || (map->type == _DRM_SHM && map->flags == _DRM_CONTAINS_LOCK))) { - map->size = size; DRM_DEBUG("Found kernel map %d\n", type); goto done; } @@ -174,20 +173,17 @@ drm_addmap(struct drm_device * dev, unsigned long offset, unsigned long size, map->flags = flags; - map->mm = drm_memrange_search_free(&dev->handle_mm, map->size, - PAGE_SIZE, 0); - if (map->mm == NULL) { + DRM_LOCK(); + ret = extent_alloc(dev->handle_ext, map->size, PAGE_SIZE, 0, + 0, EX_NOWAIT, &map->ext); + if (ret) { DRM_ERROR("can't find free offset\n"); + DRM_UNLOCK(); drm_free(map, sizeof(*map), DRM_MEM_MAPS); - return ENOMEM; - } - map->mm = drm_memrange_get_block(map->mm, map->size, - PAGE_SIZE); - if (map->mm == NULL) { - DRM_ERROR("can't get block\n"); - drm_free(map, sizeof(*map), DRM_MEM_MAPS); - return ENOMEM; + DRM_LOCK(); + return ret; } + DRM_UNLOCK(); switch (map->type) { case _DRM_REGISTERS: @@ -327,7 +323,7 @@ drm_addmap_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) request->mtrr = map->mtrr; request->handle = map->handle; - request->handle = (void *)map->mm->start; + request->handle = (void *)map->ext; return 0; } @@ -364,7 +360,9 @@ drm_rmmap(struct drm_device *dev, drm_local_map_t *map) break; } - drm_memrange_put_block(map->mm); + /* NOCOALESCE set, can't fail */ + extent_free(dev->handle_ext, map->ext, map->size, EX_NOWAIT); + drm_free(map, sizeof(*map), DRM_MEM_MAPS); } @@ -1018,7 +1016,7 @@ drm_mapbufs(struct drm_device *dev, void *data, struct drm_file *file_priv) goto done; } size = round_page(map->size); - foff = map->mm->start; + foff = map->ext; } else { size = round_page(dma->byte_count), foff = 0; diff --git a/sys/dev/pci/drm/drm_drv.c b/sys/dev/pci/drm/drm_drv.c index 8b6a448e6f7..660044ebcb4 100644 --- a/sys/dev/pci/drm/drm_drv.c +++ b/sys/dev/pci/drm/drm_drv.c @@ -220,8 +220,10 @@ drm_attach(struct device *parent, struct device *kdev, * the dma buffers api is just weird. offset 1Gb to ensure we don't * conflict with it. */ - if (drm_memrange_init(&dev->handle_mm, 1024*1024*1024, LONG_MAX) != 0) { - printf(": failed to initialise handle memrange\n"); + dev->handle_ext = extent_create("drmext", 1024*1024*1024, LONG_MAX, + M_DRM, NULL, NULL, EX_NOWAIT | EX_NOCOALESCE); + if (dev->handle_ext == NULL) { + DRM_ERROR("Failed to initialise handle extent\n"); goto error; } @@ -274,7 +276,7 @@ drm_detach(struct device *self, int flags) drm_ctxbitmap_cleanup(dev); - drm_memrange_takedown(&dev->handle_mm); + extent_destroy(dev->handle_ext); if (dev->agp && dev->agp->mtrr) { int retcode; diff --git a/sys/dev/pci/drm/drm_memrange.c b/sys/dev/pci/drm/drm_memrange.c index 5b4a9658aa4..e69de29bb2d 100644 --- a/sys/dev/pci/drm/drm_memrange.c +++ b/sys/dev/pci/drm/drm_memrange.c @@ -1,270 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - **************************************************************************/ - -/* - * Generic simple memory manager implementation. Intended to be used as a base - * class implementation for more advanced memory managers. - * - * Note that the algorithm used is quite simple and there might be substantial - * performance gains if a smarter free list is implemented. Currently it is just an - * unordered stack of free regions. This could easily be improved if an RB-tree - * is used instead. At least if we expect heavy fragmentation. - * - * Aligned allocations can also see improvement. - * - * Authors: - * Thomas Hellström <thomas-at-tungstengraphics-dot-com> - * Ported to OpenBSD by: - * Owain Ainsworth <oga@openbsd.org> - */ - -#include "drmP.h" - -int drm_memrange_create_tail_node(struct drm_memrange *, unsigned long, unsigned long); -struct drm_memrange_node *drm_memrange_split_at_start(struct - drm_memrange_node *, unsigned long); - -unsigned long -drm_memrange_tail_space(struct drm_memrange *mm) -{ - struct drm_memrange_node *entry = TAILQ_LAST(&mm->ml, drm_mmq); - - if (!entry->free) - return (0); - - return (entry->size); -} - -int -drm_memrange_remove_space_from_tail(struct drm_memrange *mm, unsigned long size) -{ - struct drm_memrange_node *entry = TAILQ_LAST(&mm->ml, drm_mmq); - - if (!entry->free) - return (ENOMEM); - - if (entry->size <= size) - return (ENOMEM); - - entry->size -=size; - return (0); -} - -int -drm_memrange_create_tail_node(struct drm_memrange *mm, unsigned long start, - unsigned long size) -{ - struct drm_memrange_node *child; - - child = (struct drm_memrange_node *)drm_calloc(1, sizeof(*child), - DRM_MEM_MM); - if (child == NULL) - return (ENOMEM); - - child->free = 1; - child->size = size; - child->start = start; - child->mm = mm; - - TAILQ_INSERT_TAIL(&mm->ml, child, ml_entry); - TAILQ_INSERT_TAIL(&mm->fl, child, fl_entry); - - return (0); -} - -int -drm_memrange_add_space_to_tail(struct drm_memrange *mm, unsigned long size) -{ - struct drm_memrange_node *entry = TAILQ_LAST(&mm->ml, drm_mmq); - - if (!entry->free) - return (drm_memrange_create_tail_node(mm, - entry->start + entry->size, size)); - entry->size += size; - return (0); - - -} - -struct drm_memrange_node * -drm_memrange_split_at_start(struct drm_memrange_node *parent, unsigned long size) -{ - struct drm_memrange_node *child; - - child = (struct drm_memrange_node *)drm_calloc(1, sizeof(*child), - DRM_MEM_MM); - if (child == NULL) - return (NULL); - - child->size = size; - child->start = parent->start; - child->mm = parent->mm; - - TAILQ_INSERT_TAIL(&child->mm->ml, child, ml_entry); - - parent->size -= size; - parent->start += size; - return (child); -} - -struct drm_memrange_node * -drm_memrange_get_block(struct drm_memrange_node *parent, unsigned long size, - unsigned alignment) -{ - struct drm_memrange_node *child, *align_splitoff = NULL; - unsigned tmp = 0; - - if (alignment) - tmp = parent->start & alignment; - - if (tmp) { - align_splitoff = drm_memrange_split_at_start(parent, - alignment - tmp); - if (align_splitoff == NULL) - return (NULL); - } - - if (parent->size == size) { - TAILQ_REMOVE(&parent->mm->fl, parent, fl_entry); - parent->free = 0; - return (parent); - } else - child = drm_memrange_split_at_start(parent, size); - - if (align_splitoff) - drm_memrange_put_block(align_splitoff); - - return (child); - -} - - -void -drm_memrange_put_block(struct drm_memrange_node *cur) -{ - struct drm_memrange *mm = cur->mm; - struct drm_memrange_node *prev_node = NULL; - struct drm_memrange_node *next_node; - int merged = 0; - - if ((prev_node = TAILQ_PREV(cur, drm_mmq, ml_entry)) != NULL) { - if (prev_node->free) { - prev_node->size += cur->size; - merged = 1; - } - } - if ((next_node = TAILQ_NEXT(cur, ml_entry)) != NULL) { - if (next_node ->free) { - if (merged) { - prev_node->size += next_node->size; - TAILQ_REMOVE(&mm->ml, next_node, - ml_entry); - TAILQ_REMOVE(&mm->fl, next_node, - fl_entry); - drm_free(next_node, sizeof(*next_node), - DRM_MEM_MM); - } - } - } - if (!merged) { - cur->free = 1; - TAILQ_INSERT_TAIL(&mm->fl, cur, fl_entry); - } else { - TAILQ_REMOVE(&mm->ml, cur, ml_entry); - drm_free(cur, sizeof(*cur), DRM_MEM_MM); - } -} - -struct drm_memrange_node * -drm_memrange_search_free(const struct drm_memrange *mm, unsigned long size, - unsigned alignment, int best_match) -{ - struct drm_memrange_node *entry, *best; - unsigned long best_size; - unsigned wasted; - - best = NULL; - best_size = ~0UL; - - TAILQ_FOREACH(entry, &mm->fl, fl_entry ) { - wasted = 0; - - if (entry->size < size) - continue; - - if (alignment) { - unsigned tmp = entry->start % alignment; - if (tmp) - wasted += alignment - tmp; - } - - if (entry->size >= size + wasted) { - if (!best_match) { - return (entry); - } - if (size < best_size) { - best = entry; - best_size = entry->size; - } - } - } - return (best); -} - -int -drm_memrange_clean(struct drm_memrange *mm) -{ - return (TAILQ_FIRST(&mm->ml) == TAILQ_LAST(&mm->ml,drm_mmq)); -} - -int -drm_memrange_init(struct drm_memrange *mm, unsigned long start, - unsigned long size) -{ - TAILQ_INIT(&mm->ml); - TAILQ_INIT(&mm->fl); - - return (drm_memrange_create_tail_node(mm, start, size)); -} - -void -drm_memrange_takedown(struct drm_memrange *mm) -{ - struct drm_memrange_node *entry; - - entry = TAILQ_FIRST(&mm->ml); - - if (!TAILQ_EMPTY(&mm->ml) || !TAILQ_EMPTY(&mm->fl)) { - DRM_ERROR("Memory manager not clean, Delaying takedown\n"); - return; - } - - TAILQ_INIT(&mm->ml); - TAILQ_INIT(&mm->fl); - drm_free(entry, sizeof(*entry), DRM_MEM_MM); -} diff --git a/sys/dev/pci/drm/drm_vm.c b/sys/dev/pci/drm/drm_vm.c index b24d8db1a80..8f6660e2189 100644 --- a/sys/dev/pci/drm/drm_vm.c +++ b/sys/dev/pci/drm/drm_vm.c @@ -76,9 +76,9 @@ drmmmap(dev_t kdev, off_t offset, int prot) */ DRM_LOCK(); TAILQ_FOREACH(map, &dev->maplist, link) { - if (offset >= map->mm->start && - offset < map->mm->start + map->size) { - offset -= map->mm->start; + if (offset >= map->ext && + offset < map->ext + map->size) { + offset -= map->ext; break; } } diff --git a/sys/dev/pci/drm/files.drm b/sys/dev/pci/drm/files.drm index 087d996ef04..3021e394dd3 100644 --- a/sys/dev/pci/drm/files.drm +++ b/sys/dev/pci/drm/files.drm @@ -1,5 +1,5 @@ # $NetBSD: files.drm,v 1.2 2007/03/28 11:29:37 jmcneill Exp $ -# $OpenBSD: files.drm,v 1.3 2008/06/26 17:01:03 oga Exp $ +# $OpenBSD: files.drm,v 1.4 2008/08/28 00:19:27 oga Exp $ # direct rendering modules define drmbase @@ -15,7 +15,6 @@ file dev/pci/drm/drm_ioctl.c drmbase file dev/pci/drm/drm_irq.c drmbase file dev/pci/drm/drm_lock.c drmbase file dev/pci/drm/drm_memory.c drmbase -file dev/pci/drm/drm_memrange.c drmbase file dev/pci/drm/drm_pci.c drmbase file dev/pci/drm/drm_scatter.c drmbase file dev/pci/drm/drm_vm.c drmbase |