replace usage of drm_memrange with extent(9). No functional change, but
authoroga <oga@openbsd.org>
Thu, 28 Aug 2008 00:19:27 +0000 (00:19 +0000)
committeroga <oga@openbsd.org>
Thu, 28 Aug 2008 00:19:27 +0000 (00:19 +0000)
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!

sys/dev/pci/drm/drmP.h
sys/dev/pci/drm/drm_bufs.c
sys/dev/pci/drm/drm_drv.c
sys/dev/pci/drm/drm_memrange.c
sys/dev/pci/drm/drm_vm.c
sys/dev/pci/drm/files.drm

index bc8f383..83a4277 100644 (file)
@@ -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;
index eb3909d..fdbf29a 100644 (file)
@@ -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;
index 8b6a448..660044e 100644 (file)
@@ -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;
index 5b4a965..e69de29 100644 (file)
@@ -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);
-}
index b24d8db..8f6660e 100644 (file)
@@ -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;
                }
        }
index 087d996..3021e39 100644 (file)
@@ -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