-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Ian Romanick wrote: > There's been quite a bit of discussion about this on #dri-devel the past > few days. I thought I'd write up a quick summary and post it to the > list. I know that there are a lot of interested parties that are on the > list, but who don't hang out in #dri-devel. :) > > As described in an old message[1], the new memory manager will be > partially in the kernel and partially in user space. The discussions in > IRC have focused on the interface between the two. Listed below are the > functions that have been discussed. The names are just made up.
I've made some slight changes to the interface, and I've even got some code (a header file anyway) to show for it. Yay me. At current count we need 6 ioctls for the memory manager. However, there are only 5 available ioctl numbers available below 0x40. Is it possible to use numbers above 0x79? The other issue that still needs to be resolved is the log. We need to figure out where to store the per-pool log, how processes find out where it's stored, and where to store the log counters. I suspect we'll want to add an additional shared area for each per-pool log, so I think we could use drmGetMap. I think we'll want to add parameters to drm_mmgr_getparam (see below) to get the size and offset of the pool's log, and we'll use those as the parameters to drmGetMap. We could probably do the same thing with the log counters. We'd just have all the log counters be on a single page. Dunno. It might be better to have a single shared area for all the logs. The first page contains an array describing the following pages: struct { const unsigned int offset; /**< Begining of log for this pool. */ const unsigned int size; /**< Size of log for this pool. */ unsigned int counter; /**< Index of next slot in log. */ }; Opinions? My intention is to spend a few extra cycles over the next couple weeks to get the kernel portion of this implemented. My goal is to get enough implemented to replace the functionality of the existing texture manager. That means *no* backing store for precious memory and no pinned objects. Once it's to that point, the user-mode drivers can start to take advantage of it. Due to demands of the $job, I'm not going to have as much time to work on this as I might like. My hope (dream?) is to get the ball rolling by doing the first kernel bits and other people will modify the user-mode drivers. > initialize_pool - Initialze a new memory pool. This will be called once > for each memory pool (e.g., on-card, AGP, PCI, etc.). > > get_pool_state - When a new process starts up it needs to know the state > of a pool. That is, it needs to know which regions are allocated or not > allocated. Since all allocations / frees are written to a log that is > stored in a circular buffer, it is possible for the log to wrap around > between times when a given processes the log. In that case the process > will also need to use this function. get_pool_state is replaced with drm_mmgr_getparam. This works similarly to the device-specific getparam commands that already exist. This single ioctl can be used to get information about the pool (number of pools, attributes of a pool, size of a pool, etc.) in addition to getting the current state of the pool. > force_log_update - The kernel updates its view of memory periodically > when processes call into it. It is possible (though very unlikely) that > a process could wrap the log between these occurances. The process can > detect this and, before wrapping the log, call this function so that the > kernel can update its view of memory. I've eliminated this call for now. I think the same thing can be accomplished by calling drm_mmgr_getparam or something. > backup_region - Regions can be marked with a "preserve" bit. This means > that the contents have to be saved before the memory can be reclaimed. > backup_region instructs the kernel to do this for a specified portion of > a region. I'll spec out this function, but I don't intend to have it implemented for the initial release. > restore_region - Restores the contents of a previously backed-up region > to a new location. Depending on how backup_region is implemented, this > function may not be necessary. This call is also eliminiated. However it is replaced by... set_backing_store - Give the kernel a buffer to store data from the region. I don't intend to have this function implemented for the initial release. > alloc_id_block - Each region is tracked by a unique ID. This function > allocates a block of these IDs to a process. They will be automatically > reclaimed if the process dies. > > release_id_block - Releases a block of previously allocated IDs. > > > [1] http://marc.theaimsgroup.com/?l=mesa3d-dev&m=111101398019810&w=2 6b8808fe6c6cf95fb69e3e576f8d3787 drm_mmgr.h -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.6 (GNU/Linux) iD8DBQFDF0lBX1gOwKyEAw8RAsqCAKCGdFSgqs0csdyCg5gDA+TNqe1dswCglXz5 EIWVwD7HeQDZr5WVQ3NUUKA= =+IVC -----END PGP SIGNATURE-----
/* * (C) Copyright IBM Corporation 2005 * 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, sublicense, * 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 NONINFRINGEMENT. IN NO EVENT SHALL * IBM 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. */ /** * \file drm_mmgr.h * Data structures and ioctls for the kernel-assised DRM memory manager. * * \author Ian Romanick <[EMAIL PROTECTED]> */ /** * DRM_IOCTL_MMGR_GETPARAM ioctl argument type. * * Get a parameter value for a DRM memory pool. * * \sa drm_mmgr_getparam_mode_t */ typedef struct drm_mmgr_getparam { /** * Name of the parameter. See \c drm_mmgr_getparam_mode_t. */ unsigned int param; unsigned int pool_id; /**< ID of the pool being queried. */ void __user * value; /**< Storage for the value being queried. */ } drm_mmgr_getparam_t; /** * Parameter names passed to the \c DRM_IOCTL_MMGR_GETPARAM ioctl. * * One of the values from this enumerant should be stored in * \c drm_mmgr_getparam_t::param when calling the \c DRM_IOCTL_MMGR_GETPARAM * ioctl. */ typedef enum { /** * Number of memory pools known to the memory manager. Returned as * an \c unsigned \c int. As might be guessed, the pool ID input is * ignored. */ DRM_MMGR_PARAM_NUM_POOLS = 1, /** * Size, in bytes, of the specified memory pool. Returned as an * \c unsigned \c int. */ DRM_MMGR_PARAM_POOL_SIZE = 2, /** * Attributes of the specified memory pool. Returned as an * \c unsigned \c int. */ DRM_MMGR_PARAM_POOL_ATTRIBUTES = 3, /** * Size, in bytes, of the complete state for the specified memory * pool. This is the amount of space required for the \c value data * returned for \c DRM_MMGR_PARAM_POOL_STATE. Returned as an * \c unsigned \c int. * * \warning * Do \b not release the lock between retrieving this value and * getting \c DRM_MMGR_PARAM_POOL_STATE. When the lock is released, * the value returned for this parameter may become invalid! */ DRM_MMGR_PARAM_POOL_STATE_SIZE = 4, /** * The complete state for the specified memory pool. * * \note * The size of the buffer required to hold the data returned for this * parameter is retrieved by the \c DRM_MMGR_PARAM_POOL_STATE_SIZE * parameter. */ DRM_MMGR_PARAM_POOL_STATE = 5, } drm_mmgr_getparam_mode_t; /** * DRM_IOCTL_MMGR_ALLOC_IDS and DRM_IOCTL_MMGR_RELEASE_IDS ioctl argument type. * * As the value returned for the DRM_IOCTL_MMGR_ALLOC_IDS ioctl, this * represents the first region ID allocated to the process and the number of * IDs allocated. As the input to the DRM_IOCTL_MMGR_RELEASE_IDS ioctl, this * represents the first region ID to be released and the number of IDs to be * released. */ typedef struct drm_mmgr_region_id_range { unsigned int base_id; /**< First region ID. */ unsigned int count; /**< Number of IDs. */ } drm_mmgr_region_id_range_t; /** * DRM_IOCTL_MMGR_INIT_POOL ioctl argument type. */ typedef struct drm_mmgr_init_pool { unsigned int pool_id; /**< ID for the pool. */ unsigned int size; /**< Size, in bytes, of the pool. */ unsigned int attributes; /**< Attributes bits for the pool. */ } drm_mmgr_init_pool_t; /** * DRM_IOCTL_MMGR_BACKUP_REGION ioctl argument type. * * Specifies that \c size bytes at \c offset of the pool named \c pool_id are * to be backed up. * * \todo * Is the region_id needed? What happens if the speicified offset and size * span multiple regions? I'd like to avoid having the kernel search the * memory list for the data that needs to be backed up, but that may be * inevitable. */ typedef struct drm_mmgr_backup_region { unsigned int region_id; /**< ID of the region to be backed up. */ unsigned int pool_id; /**< ID of the pool holding \c region_id. */ unsigned int offset; /**< Offset from \b pool base. */ unsigned int size; /**< Number of bytes to backup. */ } drm_mmgr_backup_region_t ; /** * DRM_IOCTL_MMGR_SET_BACKING ioctl argument type. * * Specifies the buffer to be used as backing store for \c region_id. */ typedef struct drm_mmgr_backing_store { unsigned int region_id; /**< ID of the region to be backed up. */ void __user * buffer; /**< Buffer used to back the region. */ unsigned int size; /**< Size of \c buffer. */ } drm_mmgr_backing_store_t;