183827f40a2d97261528087331b0bee6ce2cf27c5root/************************************************************************** 283827f40a2d97261528087331b0bee6ce2cf27c5root * 383827f40a2d97261528087331b0bee6ce2cf27c5root * Copyright 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA 483827f40a2d97261528087331b0bee6ce2cf27c5root * All Rights Reserved. 583827f40a2d97261528087331b0bee6ce2cf27c5root * Copyright 2009 VMware, Inc., Palo Alto, CA., USA 683827f40a2d97261528087331b0bee6ce2cf27c5root * All Rights Reserved. 783827f40a2d97261528087331b0bee6ce2cf27c5root * 883827f40a2d97261528087331b0bee6ce2cf27c5root * Permission is hereby granted, free of charge, to any person obtaining a 983827f40a2d97261528087331b0bee6ce2cf27c5root * copy of this software and associated documentation files (the 1083827f40a2d97261528087331b0bee6ce2cf27c5root * "Software"), to deal in the Software without restriction, including 1183827f40a2d97261528087331b0bee6ce2cf27c5root * without limitation the rights to use, copy, modify, merge, publish, 1283827f40a2d97261528087331b0bee6ce2cf27c5root * distribute, sub license, and/or sell copies of the Software, and to 1383827f40a2d97261528087331b0bee6ce2cf27c5root * permit persons to whom the Software is furnished to do so, subject to 1483827f40a2d97261528087331b0bee6ce2cf27c5root * the following conditions: 1583827f40a2d97261528087331b0bee6ce2cf27c5root * 1683827f40a2d97261528087331b0bee6ce2cf27c5root * The above copyright notice and this permission notice (including the 1783827f40a2d97261528087331b0bee6ce2cf27c5root * next paragraph) shall be included in all copies or substantial portions 1883827f40a2d97261528087331b0bee6ce2cf27c5root * of the Software. 1983827f40a2d97261528087331b0bee6ce2cf27c5root * 2083827f40a2d97261528087331b0bee6ce2cf27c5root * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 2183827f40a2d97261528087331b0bee6ce2cf27c5root * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 2283827f40a2d97261528087331b0bee6ce2cf27c5root * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 2383827f40a2d97261528087331b0bee6ce2cf27c5root * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, 2483827f40a2d97261528087331b0bee6ce2cf27c5root * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 2583827f40a2d97261528087331b0bee6ce2cf27c5root * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 2683827f40a2d97261528087331b0bee6ce2cf27c5root * USE OR OTHER DEALINGS IN THE SOFTWARE. 2783827f40a2d97261528087331b0bee6ce2cf27c5root * 2883827f40a2d97261528087331b0bee6ce2cf27c5root **************************************************************************/ 2983827f40a2d97261528087331b0bee6ce2cf27c5root/* 3083827f40a2d97261528087331b0bee6ce2cf27c5root * Authors: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com> 3183827f40a2d97261528087331b0bee6ce2cf27c5root */ 3283827f40a2d97261528087331b0bee6ce2cf27c5root 3383827f40a2d97261528087331b0bee6ce2cf27c5root#ifdef HAVE_CONFIG_H 3483827f40a2d97261528087331b0bee6ce2cf27c5root#include "config.h" 3583827f40a2d97261528087331b0bee6ce2cf27c5root#endif 3683827f40a2d97261528087331b0bee6ce2cf27c5root 3777bfea2e6a3dc1e30a17780b48b7b231eef77255Thierry Strudel#include <drm/psb_ttm_placement_user.h> 3883827f40a2d97261528087331b0bee6ce2cf27c5root#include <stdint.h> 3983827f40a2d97261528087331b0bee6ce2cf27c5root#include <sys/time.h> 4083827f40a2d97261528087331b0bee6ce2cf27c5root#include <errno.h> 4183827f40a2d97261528087331b0bee6ce2cf27c5root#include <unistd.h> 4283827f40a2d97261528087331b0bee6ce2cf27c5root#include <assert.h> 4383827f40a2d97261528087331b0bee6ce2cf27c5root#include <string.h> 4483827f40a2d97261528087331b0bee6ce2cf27c5root#include <sys/mman.h> 4583827f40a2d97261528087331b0bee6ce2cf27c5root#include <xf86drm.h> 4683827f40a2d97261528087331b0bee6ce2cf27c5root#include "wsbm_pool.h" 4783827f40a2d97261528087331b0bee6ce2cf27c5root#include "wsbm_fencemgr.h" 4883827f40a2d97261528087331b0bee6ce2cf27c5root#include "wsbm_priv.h" 4983827f40a2d97261528087331b0bee6ce2cf27c5root#include "wsbm_manager.h" 5083827f40a2d97261528087331b0bee6ce2cf27c5root 5183827f40a2d97261528087331b0bee6ce2cf27c5root#define WSBM_SLABPOOL_ALLOC_RETRIES 100 5283827f40a2d97261528087331b0bee6ce2cf27c5root#define DRMRESTARTCOMMANDWRITE(_fd, _val, _arg, _ret) \ 5383827f40a2d97261528087331b0bee6ce2cf27c5root do { \ 5483827f40a2d97261528087331b0bee6ce2cf27c5root (_ret) = drmCommandWrite(_fd, _val, &(_arg), sizeof(_arg)); \ 5583827f40a2d97261528087331b0bee6ce2cf27c5root } while ((_ret) == -EAGAIN || (_ret) == -ERESTART); \ 5683827f40a2d97261528087331b0bee6ce2cf27c5root 5783827f40a2d97261528087331b0bee6ce2cf27c5root#define DRMRESTARTCOMMANDWRITEREAD(_fd, _val, _arg, _ret) \ 5883827f40a2d97261528087331b0bee6ce2cf27c5root do { \ 5983827f40a2d97261528087331b0bee6ce2cf27c5root (_ret) = drmCommandWriteRead(_fd, _val, &(_arg), sizeof(_arg)); \ 6083827f40a2d97261528087331b0bee6ce2cf27c5root } while ((_ret) == -EAGAIN || (_ret) == -ERESTART); \ 6183827f40a2d97261528087331b0bee6ce2cf27c5root 6283827f40a2d97261528087331b0bee6ce2cf27c5root 6383827f40a2d97261528087331b0bee6ce2cf27c5root#ifdef DEBUG_FENCESIGNALED 6483827f40a2d97261528087331b0bee6ce2cf27c5rootstatic int createbuffer = 0; 6583827f40a2d97261528087331b0bee6ce2cf27c5rootstatic int fencesignaled = 0; 6683827f40a2d97261528087331b0bee6ce2cf27c5root#endif 6783827f40a2d97261528087331b0bee6ce2cf27c5root 6883827f40a2d97261528087331b0bee6ce2cf27c5rootstruct _WsbmSlab; 6983827f40a2d97261528087331b0bee6ce2cf27c5root 7083827f40a2d97261528087331b0bee6ce2cf27c5rootstruct _WsbmSlabBuffer 7183827f40a2d97261528087331b0bee6ce2cf27c5root{ 7283827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmKernelBuf kBuf; 7383827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmBufStorage storage; 7483827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmCond event; 7583827f40a2d97261528087331b0bee6ce2cf27c5root 7683827f40a2d97261528087331b0bee6ce2cf27c5root /* 7783827f40a2d97261528087331b0bee6ce2cf27c5root * Remains constant after creation. 7883827f40a2d97261528087331b0bee6ce2cf27c5root */ 7983827f40a2d97261528087331b0bee6ce2cf27c5root 8083827f40a2d97261528087331b0bee6ce2cf27c5root int isSlabBuffer; 8183827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmSlab *parent; 8283827f40a2d97261528087331b0bee6ce2cf27c5root uint32_t start; 8383827f40a2d97261528087331b0bee6ce2cf27c5root void *virtual; 8483827f40a2d97261528087331b0bee6ce2cf27c5root unsigned long requestedSize; 8583827f40a2d97261528087331b0bee6ce2cf27c5root uint64_t mapHandle; 8683827f40a2d97261528087331b0bee6ce2cf27c5root 8783827f40a2d97261528087331b0bee6ce2cf27c5root /* 8883827f40a2d97261528087331b0bee6ce2cf27c5root * Protected by struct _WsbmSlabSizeHeader::mutex 8983827f40a2d97261528087331b0bee6ce2cf27c5root */ 9083827f40a2d97261528087331b0bee6ce2cf27c5root 9183827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmListHead head; 9283827f40a2d97261528087331b0bee6ce2cf27c5root 9383827f40a2d97261528087331b0bee6ce2cf27c5root /* 9483827f40a2d97261528087331b0bee6ce2cf27c5root * Protected by this::mutex 9583827f40a2d97261528087331b0bee6ce2cf27c5root */ 9683827f40a2d97261528087331b0bee6ce2cf27c5root 9783827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmFenceObject *fence; 9883827f40a2d97261528087331b0bee6ce2cf27c5root uint32_t fenceType; 9983827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmAtomic writers; /* (Only upping) */ 10083827f40a2d97261528087331b0bee6ce2cf27c5root int unFenced; 10183827f40a2d97261528087331b0bee6ce2cf27c5root}; 10283827f40a2d97261528087331b0bee6ce2cf27c5root 10383827f40a2d97261528087331b0bee6ce2cf27c5rootstruct _WsbmSlabPool; 10483827f40a2d97261528087331b0bee6ce2cf27c5rootstruct _WsbmSlabKernelBO 10583827f40a2d97261528087331b0bee6ce2cf27c5root{ 10683827f40a2d97261528087331b0bee6ce2cf27c5root 10783827f40a2d97261528087331b0bee6ce2cf27c5root /* 10883827f40a2d97261528087331b0bee6ce2cf27c5root * Constant at creation 10983827f40a2d97261528087331b0bee6ce2cf27c5root */ 11083827f40a2d97261528087331b0bee6ce2cf27c5root 11183827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmKernelBuf kBuf; 11283827f40a2d97261528087331b0bee6ce2cf27c5root uint32_t pageAlignment; 11383827f40a2d97261528087331b0bee6ce2cf27c5root void *virtual; 11483827f40a2d97261528087331b0bee6ce2cf27c5root unsigned long actualSize; 11583827f40a2d97261528087331b0bee6ce2cf27c5root uint64_t mapHandle; 11683827f40a2d97261528087331b0bee6ce2cf27c5root 11783827f40a2d97261528087331b0bee6ce2cf27c5root /* 11883827f40a2d97261528087331b0bee6ce2cf27c5root * Protected by struct _WsbmSlabCache::mutex 11983827f40a2d97261528087331b0bee6ce2cf27c5root */ 12083827f40a2d97261528087331b0bee6ce2cf27c5root 12183827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmSlabPool *slabPool; 12283827f40a2d97261528087331b0bee6ce2cf27c5root uint32_t proposedPlacement; 12383827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmListHead timeoutHead; 12483827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmListHead head; 12583827f40a2d97261528087331b0bee6ce2cf27c5root struct timeval timeFreed; 12683827f40a2d97261528087331b0bee6ce2cf27c5root}; 12783827f40a2d97261528087331b0bee6ce2cf27c5root 12883827f40a2d97261528087331b0bee6ce2cf27c5rootstruct _WsbmSlab 12983827f40a2d97261528087331b0bee6ce2cf27c5root{ 13083827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmListHead head; 13183827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmListHead freeBuffers; 13283827f40a2d97261528087331b0bee6ce2cf27c5root uint32_t numBuffers; 13383827f40a2d97261528087331b0bee6ce2cf27c5root uint32_t numFree; 13483827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmSlabBuffer *buffers; 13583827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmSlabSizeHeader *header; 13683827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmSlabKernelBO *kbo; 13783827f40a2d97261528087331b0bee6ce2cf27c5root}; 13883827f40a2d97261528087331b0bee6ce2cf27c5root 13983827f40a2d97261528087331b0bee6ce2cf27c5rootstruct _WsbmSlabSizeHeader 14083827f40a2d97261528087331b0bee6ce2cf27c5root{ 14183827f40a2d97261528087331b0bee6ce2cf27c5root /* 14283827f40a2d97261528087331b0bee6ce2cf27c5root * Constant at creation. 14383827f40a2d97261528087331b0bee6ce2cf27c5root */ 14483827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmSlabPool *slabPool; 14583827f40a2d97261528087331b0bee6ce2cf27c5root uint32_t bufSize; 14683827f40a2d97261528087331b0bee6ce2cf27c5root 14783827f40a2d97261528087331b0bee6ce2cf27c5root /* 14883827f40a2d97261528087331b0bee6ce2cf27c5root * Protected by this::mutex 14983827f40a2d97261528087331b0bee6ce2cf27c5root */ 15083827f40a2d97261528087331b0bee6ce2cf27c5root 15183827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmListHead slabs; 15283827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmListHead freeSlabs; 15383827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmListHead delayedBuffers; 15483827f40a2d97261528087331b0bee6ce2cf27c5root uint32_t numDelayed; 15583827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmMutex mutex; 15683827f40a2d97261528087331b0bee6ce2cf27c5root}; 15783827f40a2d97261528087331b0bee6ce2cf27c5root 15883827f40a2d97261528087331b0bee6ce2cf27c5rootstruct _WsbmSlabCache 15983827f40a2d97261528087331b0bee6ce2cf27c5root{ 16083827f40a2d97261528087331b0bee6ce2cf27c5root struct timeval slabTimeout; 16183827f40a2d97261528087331b0bee6ce2cf27c5root struct timeval checkInterval; 16283827f40a2d97261528087331b0bee6ce2cf27c5root struct timeval nextCheck; 16383827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmListHead timeoutList; 16483827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmListHead unCached; 16583827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmListHead cached; 16683827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmMutex mutex; 16783827f40a2d97261528087331b0bee6ce2cf27c5root}; 16883827f40a2d97261528087331b0bee6ce2cf27c5root 16983827f40a2d97261528087331b0bee6ce2cf27c5rootstruct _WsbmSlabPool 17083827f40a2d97261528087331b0bee6ce2cf27c5root{ 17183827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmBufferPool pool; 17283827f40a2d97261528087331b0bee6ce2cf27c5root 17383827f40a2d97261528087331b0bee6ce2cf27c5root /* 17483827f40a2d97261528087331b0bee6ce2cf27c5root * The data of this structure remains constant after 17583827f40a2d97261528087331b0bee6ce2cf27c5root * initialization and thus needs no mutex protection. 17683827f40a2d97261528087331b0bee6ce2cf27c5root */ 17783827f40a2d97261528087331b0bee6ce2cf27c5root 17883827f40a2d97261528087331b0bee6ce2cf27c5root unsigned int devOffset; 17983827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmSlabCache *cache; 18083827f40a2d97261528087331b0bee6ce2cf27c5root uint32_t proposedPlacement; 18183827f40a2d97261528087331b0bee6ce2cf27c5root uint32_t validMask; 18283827f40a2d97261528087331b0bee6ce2cf27c5root uint32_t *bucketSizes; 18383827f40a2d97261528087331b0bee6ce2cf27c5root uint32_t numBuckets; 18483827f40a2d97261528087331b0bee6ce2cf27c5root uint32_t pageSize; 18583827f40a2d97261528087331b0bee6ce2cf27c5root int pageAlignment; 18683827f40a2d97261528087331b0bee6ce2cf27c5root int maxSlabSize; 18783827f40a2d97261528087331b0bee6ce2cf27c5root int desiredNumBuffers; 18883827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmSlabSizeHeader *headers; 18983827f40a2d97261528087331b0bee6ce2cf27c5root}; 19083827f40a2d97261528087331b0bee6ce2cf27c5root 19183827f40a2d97261528087331b0bee6ce2cf27c5rootstatic inline struct _WsbmSlabPool * 19283827f40a2d97261528087331b0bee6ce2cf27c5rootslabPoolFromPool(struct _WsbmBufferPool *pool) 19383827f40a2d97261528087331b0bee6ce2cf27c5root{ 19483827f40a2d97261528087331b0bee6ce2cf27c5root return containerOf(pool, struct _WsbmSlabPool, pool); 19583827f40a2d97261528087331b0bee6ce2cf27c5root} 19683827f40a2d97261528087331b0bee6ce2cf27c5root 19783827f40a2d97261528087331b0bee6ce2cf27c5rootstatic inline struct _WsbmSlabPool * 19883827f40a2d97261528087331b0bee6ce2cf27c5rootslabPoolFromBuf(struct _WsbmSlabBuffer *sBuf) 19983827f40a2d97261528087331b0bee6ce2cf27c5root{ 20083827f40a2d97261528087331b0bee6ce2cf27c5root return slabPoolFromPool(sBuf->storage.pool); 20183827f40a2d97261528087331b0bee6ce2cf27c5root} 20283827f40a2d97261528087331b0bee6ce2cf27c5root 20383827f40a2d97261528087331b0bee6ce2cf27c5rootstatic inline struct _WsbmSlabBuffer * 20483827f40a2d97261528087331b0bee6ce2cf27c5rootslabBuffer(struct _WsbmBufStorage *buf) 20583827f40a2d97261528087331b0bee6ce2cf27c5root{ 20683827f40a2d97261528087331b0bee6ce2cf27c5root return containerOf(buf, struct _WsbmSlabBuffer, storage); 20783827f40a2d97261528087331b0bee6ce2cf27c5root} 20883827f40a2d97261528087331b0bee6ce2cf27c5root 20983827f40a2d97261528087331b0bee6ce2cf27c5root/* 21083827f40a2d97261528087331b0bee6ce2cf27c5root * FIXME: Perhaps arrange timeout slabs in size buckets for fast 21183827f40a2d97261528087331b0bee6ce2cf27c5root * retreival?? 21283827f40a2d97261528087331b0bee6ce2cf27c5root */ 21383827f40a2d97261528087331b0bee6ce2cf27c5root 21483827f40a2d97261528087331b0bee6ce2cf27c5rootstatic inline int 21583827f40a2d97261528087331b0bee6ce2cf27c5rootwsbmTimeAfterEq(struct timeval *arg1, struct timeval *arg2) 21683827f40a2d97261528087331b0bee6ce2cf27c5root{ 21783827f40a2d97261528087331b0bee6ce2cf27c5root return ((arg1->tv_sec > arg2->tv_sec) || 21883827f40a2d97261528087331b0bee6ce2cf27c5root ((arg1->tv_sec == arg2->tv_sec) && 21983827f40a2d97261528087331b0bee6ce2cf27c5root (arg1->tv_usec > arg2->tv_usec))); 22083827f40a2d97261528087331b0bee6ce2cf27c5root} 22183827f40a2d97261528087331b0bee6ce2cf27c5root 22283827f40a2d97261528087331b0bee6ce2cf27c5rootstatic inline void 22383827f40a2d97261528087331b0bee6ce2cf27c5rootwsbmTimeAdd(struct timeval *arg, struct timeval *add) 22483827f40a2d97261528087331b0bee6ce2cf27c5root{ 22583827f40a2d97261528087331b0bee6ce2cf27c5root unsigned int sec; 22683827f40a2d97261528087331b0bee6ce2cf27c5root 22783827f40a2d97261528087331b0bee6ce2cf27c5root arg->tv_sec += add->tv_sec; 22883827f40a2d97261528087331b0bee6ce2cf27c5root arg->tv_usec += add->tv_usec; 22983827f40a2d97261528087331b0bee6ce2cf27c5root sec = arg->tv_usec / 1000000; 23083827f40a2d97261528087331b0bee6ce2cf27c5root arg->tv_sec += sec; 23183827f40a2d97261528087331b0bee6ce2cf27c5root arg->tv_usec -= sec * 1000000; 23283827f40a2d97261528087331b0bee6ce2cf27c5root} 23383827f40a2d97261528087331b0bee6ce2cf27c5root 23483827f40a2d97261528087331b0bee6ce2cf27c5rootstatic void 23583827f40a2d97261528087331b0bee6ce2cf27c5rootwsbmFreeKernelBO(struct _WsbmSlabKernelBO *kbo) 23683827f40a2d97261528087331b0bee6ce2cf27c5root{ 23783827f40a2d97261528087331b0bee6ce2cf27c5root struct ttm_pl_reference_req arg; 23883827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmSlabPool *slabPool; 23983827f40a2d97261528087331b0bee6ce2cf27c5root 24083827f40a2d97261528087331b0bee6ce2cf27c5root if (!kbo) 24183827f40a2d97261528087331b0bee6ce2cf27c5root return; 24283827f40a2d97261528087331b0bee6ce2cf27c5root 24383827f40a2d97261528087331b0bee6ce2cf27c5root slabPool = kbo->slabPool; 24483827f40a2d97261528087331b0bee6ce2cf27c5root arg.handle = kbo->kBuf.handle; 24583827f40a2d97261528087331b0bee6ce2cf27c5root (void)munmap(kbo->virtual, kbo->actualSize); 24683827f40a2d97261528087331b0bee6ce2cf27c5root (void)drmCommandWrite(slabPool->pool.fd, 24783827f40a2d97261528087331b0bee6ce2cf27c5root slabPool->devOffset + TTM_PL_UNREF, &arg, 24883827f40a2d97261528087331b0bee6ce2cf27c5root sizeof(arg)); 24983827f40a2d97261528087331b0bee6ce2cf27c5root free(kbo); 25083827f40a2d97261528087331b0bee6ce2cf27c5root} 25183827f40a2d97261528087331b0bee6ce2cf27c5root 25283827f40a2d97261528087331b0bee6ce2cf27c5rootstatic void 25383827f40a2d97261528087331b0bee6ce2cf27c5rootwsbmFreeTimeoutKBOsLocked(struct _WsbmSlabCache *cache, struct timeval *time) 25483827f40a2d97261528087331b0bee6ce2cf27c5root{ 25583827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmListHead *list, *next; 25683827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmSlabKernelBO *kbo; 25783827f40a2d97261528087331b0bee6ce2cf27c5root 25883827f40a2d97261528087331b0bee6ce2cf27c5root if (!wsbmTimeAfterEq(time, &cache->nextCheck)) 25983827f40a2d97261528087331b0bee6ce2cf27c5root return; 26083827f40a2d97261528087331b0bee6ce2cf27c5root 26183827f40a2d97261528087331b0bee6ce2cf27c5root WSBMLISTFOREACHSAFE(list, next, &cache->timeoutList) { 26283827f40a2d97261528087331b0bee6ce2cf27c5root kbo = WSBMLISTENTRY(list, struct _WsbmSlabKernelBO, timeoutHead); 26383827f40a2d97261528087331b0bee6ce2cf27c5root 26483827f40a2d97261528087331b0bee6ce2cf27c5root if (!wsbmTimeAfterEq(time, &kbo->timeFreed)) 26583827f40a2d97261528087331b0bee6ce2cf27c5root break; 26683827f40a2d97261528087331b0bee6ce2cf27c5root 26783827f40a2d97261528087331b0bee6ce2cf27c5root WSBMLISTDELINIT(&kbo->timeoutHead); 26883827f40a2d97261528087331b0bee6ce2cf27c5root WSBMLISTDELINIT(&kbo->head); 26983827f40a2d97261528087331b0bee6ce2cf27c5root wsbmFreeKernelBO(kbo); 27083827f40a2d97261528087331b0bee6ce2cf27c5root } 27183827f40a2d97261528087331b0bee6ce2cf27c5root 27283827f40a2d97261528087331b0bee6ce2cf27c5root cache->nextCheck = *time; 27383827f40a2d97261528087331b0bee6ce2cf27c5root wsbmTimeAdd(&cache->nextCheck, &cache->checkInterval); 27483827f40a2d97261528087331b0bee6ce2cf27c5root} 27583827f40a2d97261528087331b0bee6ce2cf27c5root 27683827f40a2d97261528087331b0bee6ce2cf27c5root/* 27783827f40a2d97261528087331b0bee6ce2cf27c5root * Add a _SlabKernelBO to the free slab manager. 27883827f40a2d97261528087331b0bee6ce2cf27c5root * This means that it is available for reuse, but if it's not 27983827f40a2d97261528087331b0bee6ce2cf27c5root * reused in a while, it will be freed. 28083827f40a2d97261528087331b0bee6ce2cf27c5root */ 28183827f40a2d97261528087331b0bee6ce2cf27c5root 28283827f40a2d97261528087331b0bee6ce2cf27c5rootstatic void 28383827f40a2d97261528087331b0bee6ce2cf27c5rootwsbmSetKernelBOFree(struct _WsbmSlabCache *cache, 28483827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmSlabKernelBO *kbo) 28583827f40a2d97261528087331b0bee6ce2cf27c5root{ 28683827f40a2d97261528087331b0bee6ce2cf27c5root struct timeval time; 28783827f40a2d97261528087331b0bee6ce2cf27c5root struct timeval timeFreed; 28883827f40a2d97261528087331b0bee6ce2cf27c5root 28983827f40a2d97261528087331b0bee6ce2cf27c5root gettimeofday(&time, NULL); 29083827f40a2d97261528087331b0bee6ce2cf27c5root timeFreed = time; 29183827f40a2d97261528087331b0bee6ce2cf27c5root WSBM_MUTEX_LOCK(&cache->mutex); 29283827f40a2d97261528087331b0bee6ce2cf27c5root wsbmTimeAdd(&timeFreed, &cache->slabTimeout); 29383827f40a2d97261528087331b0bee6ce2cf27c5root kbo->timeFreed = timeFreed; 29483827f40a2d97261528087331b0bee6ce2cf27c5root 29583827f40a2d97261528087331b0bee6ce2cf27c5root if (kbo->kBuf.placement & TTM_PL_FLAG_CACHED) 29683827f40a2d97261528087331b0bee6ce2cf27c5root WSBMLISTADD(&kbo->head, &cache->cached); 29783827f40a2d97261528087331b0bee6ce2cf27c5root else 29883827f40a2d97261528087331b0bee6ce2cf27c5root WSBMLISTADD(&kbo->head, &cache->unCached); 29983827f40a2d97261528087331b0bee6ce2cf27c5root 30083827f40a2d97261528087331b0bee6ce2cf27c5root WSBMLISTADDTAIL(&kbo->timeoutHead, &cache->timeoutList); 30183827f40a2d97261528087331b0bee6ce2cf27c5root wsbmFreeTimeoutKBOsLocked(cache, &time); 30283827f40a2d97261528087331b0bee6ce2cf27c5root 30383827f40a2d97261528087331b0bee6ce2cf27c5root WSBM_MUTEX_UNLOCK(&cache->mutex); 30483827f40a2d97261528087331b0bee6ce2cf27c5root} 30583827f40a2d97261528087331b0bee6ce2cf27c5root 30683827f40a2d97261528087331b0bee6ce2cf27c5root/* 30783827f40a2d97261528087331b0bee6ce2cf27c5root * Get a _SlabKernelBO for us to use as storage for a slab. 30883827f40a2d97261528087331b0bee6ce2cf27c5root */ 30983827f40a2d97261528087331b0bee6ce2cf27c5root 31083827f40a2d97261528087331b0bee6ce2cf27c5rootstatic struct _WsbmSlabKernelBO * 31183827f40a2d97261528087331b0bee6ce2cf27c5rootwsbmAllocKernelBO(struct _WsbmSlabSizeHeader *header) 31283827f40a2d97261528087331b0bee6ce2cf27c5root{ 31383827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmSlabPool *slabPool = header->slabPool; 31483827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmSlabCache *cache = slabPool->cache; 31583827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmListHead *list, *head; 31683827f40a2d97261528087331b0bee6ce2cf27c5root uint32_t size = header->bufSize * slabPool->desiredNumBuffers; 31783827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmSlabKernelBO *kbo; 31883827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmSlabKernelBO *kboTmp; 31983827f40a2d97261528087331b0bee6ce2cf27c5root int ret; 32083827f40a2d97261528087331b0bee6ce2cf27c5root 32183827f40a2d97261528087331b0bee6ce2cf27c5root /* 32283827f40a2d97261528087331b0bee6ce2cf27c5root * FIXME: We should perhaps allow some variation in slabsize in order 32383827f40a2d97261528087331b0bee6ce2cf27c5root * to efficiently reuse slabs. 32483827f40a2d97261528087331b0bee6ce2cf27c5root */ 32583827f40a2d97261528087331b0bee6ce2cf27c5root 3263795b36d0c937666a5bddc352c781d5e0beec26bThierry Strudel size = (size <= (uint32_t) slabPool->maxSlabSize) ? size : (uint32_t) slabPool->maxSlabSize; 32783827f40a2d97261528087331b0bee6ce2cf27c5root if (size < header->bufSize) 32883827f40a2d97261528087331b0bee6ce2cf27c5root size = header->bufSize; 32983827f40a2d97261528087331b0bee6ce2cf27c5root size = (size + slabPool->pageSize - 1) & ~(slabPool->pageSize - 1); 33083827f40a2d97261528087331b0bee6ce2cf27c5root WSBM_MUTEX_LOCK(&cache->mutex); 33183827f40a2d97261528087331b0bee6ce2cf27c5root 33283827f40a2d97261528087331b0bee6ce2cf27c5root kbo = NULL; 33383827f40a2d97261528087331b0bee6ce2cf27c5root 33483827f40a2d97261528087331b0bee6ce2cf27c5root retry: 33583827f40a2d97261528087331b0bee6ce2cf27c5root head = (slabPool->proposedPlacement & TTM_PL_FLAG_CACHED) ? 33683827f40a2d97261528087331b0bee6ce2cf27c5root &cache->cached : &cache->unCached; 33783827f40a2d97261528087331b0bee6ce2cf27c5root 33883827f40a2d97261528087331b0bee6ce2cf27c5root WSBMLISTFOREACH(list, head) { 33983827f40a2d97261528087331b0bee6ce2cf27c5root kboTmp = WSBMLISTENTRY(list, struct _WsbmSlabKernelBO, head); 34083827f40a2d97261528087331b0bee6ce2cf27c5root 34183827f40a2d97261528087331b0bee6ce2cf27c5root if ((kboTmp->actualSize == size) && 34283827f40a2d97261528087331b0bee6ce2cf27c5root (slabPool->pageAlignment == 0 || 34383827f40a2d97261528087331b0bee6ce2cf27c5root (kboTmp->pageAlignment % slabPool->pageAlignment) == 0)) { 34483827f40a2d97261528087331b0bee6ce2cf27c5root 34583827f40a2d97261528087331b0bee6ce2cf27c5root if (!kbo) 34683827f40a2d97261528087331b0bee6ce2cf27c5root kbo = kboTmp; 34783827f40a2d97261528087331b0bee6ce2cf27c5root 34883827f40a2d97261528087331b0bee6ce2cf27c5root if ((kbo->proposedPlacement ^ slabPool->proposedPlacement) == 0) 34983827f40a2d97261528087331b0bee6ce2cf27c5root break; 35083827f40a2d97261528087331b0bee6ce2cf27c5root 35183827f40a2d97261528087331b0bee6ce2cf27c5root } 35283827f40a2d97261528087331b0bee6ce2cf27c5root } 35383827f40a2d97261528087331b0bee6ce2cf27c5root 35483827f40a2d97261528087331b0bee6ce2cf27c5root if (kbo) { 35583827f40a2d97261528087331b0bee6ce2cf27c5root WSBMLISTDELINIT(&kbo->head); 35683827f40a2d97261528087331b0bee6ce2cf27c5root WSBMLISTDELINIT(&kbo->timeoutHead); 35783827f40a2d97261528087331b0bee6ce2cf27c5root } 35883827f40a2d97261528087331b0bee6ce2cf27c5root 35983827f40a2d97261528087331b0bee6ce2cf27c5root WSBM_MUTEX_UNLOCK(&cache->mutex); 36083827f40a2d97261528087331b0bee6ce2cf27c5root 36183827f40a2d97261528087331b0bee6ce2cf27c5root if (kbo) { 36283827f40a2d97261528087331b0bee6ce2cf27c5root uint32_t new_mask = 36383827f40a2d97261528087331b0bee6ce2cf27c5root kbo->proposedPlacement ^ slabPool->proposedPlacement; 36483827f40a2d97261528087331b0bee6ce2cf27c5root 36583827f40a2d97261528087331b0bee6ce2cf27c5root ret = 0; 36683827f40a2d97261528087331b0bee6ce2cf27c5root if (new_mask) { 36783827f40a2d97261528087331b0bee6ce2cf27c5root union ttm_pl_setstatus_arg arg; 36883827f40a2d97261528087331b0bee6ce2cf27c5root struct ttm_pl_setstatus_req *req = &arg.req; 36983827f40a2d97261528087331b0bee6ce2cf27c5root struct ttm_pl_rep *rep = &arg.rep; 37083827f40a2d97261528087331b0bee6ce2cf27c5root 37183827f40a2d97261528087331b0bee6ce2cf27c5root req->handle = kbo->kBuf.handle; 37283827f40a2d97261528087331b0bee6ce2cf27c5root req->set_placement = slabPool->proposedPlacement & new_mask; 37383827f40a2d97261528087331b0bee6ce2cf27c5root req->clr_placement = ~slabPool->proposedPlacement & new_mask; 37483827f40a2d97261528087331b0bee6ce2cf27c5root DRMRESTARTCOMMANDWRITEREAD(slabPool->pool.fd, 37583827f40a2d97261528087331b0bee6ce2cf27c5root slabPool->devOffset + TTM_PL_SETSTATUS, 37683827f40a2d97261528087331b0bee6ce2cf27c5root arg, ret); 37783827f40a2d97261528087331b0bee6ce2cf27c5root if (ret == 0) { 37883827f40a2d97261528087331b0bee6ce2cf27c5root kbo->kBuf.gpuOffset = rep->gpu_offset; 37983827f40a2d97261528087331b0bee6ce2cf27c5root kbo->kBuf.placement = rep->placement; 38083827f40a2d97261528087331b0bee6ce2cf27c5root } 38183827f40a2d97261528087331b0bee6ce2cf27c5root kbo->proposedPlacement = slabPool->proposedPlacement; 38283827f40a2d97261528087331b0bee6ce2cf27c5root } 38383827f40a2d97261528087331b0bee6ce2cf27c5root 38483827f40a2d97261528087331b0bee6ce2cf27c5root if (ret == 0) 38583827f40a2d97261528087331b0bee6ce2cf27c5root return kbo; 38683827f40a2d97261528087331b0bee6ce2cf27c5root 38783827f40a2d97261528087331b0bee6ce2cf27c5root wsbmFreeKernelBO(kbo); 38883827f40a2d97261528087331b0bee6ce2cf27c5root kbo = NULL; 38983827f40a2d97261528087331b0bee6ce2cf27c5root goto retry; 39083827f40a2d97261528087331b0bee6ce2cf27c5root } 39183827f40a2d97261528087331b0bee6ce2cf27c5root 39283827f40a2d97261528087331b0bee6ce2cf27c5root kbo = calloc(1, sizeof(*kbo)); 39383827f40a2d97261528087331b0bee6ce2cf27c5root if (!kbo) 39483827f40a2d97261528087331b0bee6ce2cf27c5root return NULL; 39583827f40a2d97261528087331b0bee6ce2cf27c5root 39683827f40a2d97261528087331b0bee6ce2cf27c5root { 39783827f40a2d97261528087331b0bee6ce2cf27c5root union ttm_pl_create_arg arg; 39883827f40a2d97261528087331b0bee6ce2cf27c5root 39983827f40a2d97261528087331b0bee6ce2cf27c5root kbo->slabPool = slabPool; 40083827f40a2d97261528087331b0bee6ce2cf27c5root WSBMINITLISTHEAD(&kbo->head); 40183827f40a2d97261528087331b0bee6ce2cf27c5root WSBMINITLISTHEAD(&kbo->timeoutHead); 40283827f40a2d97261528087331b0bee6ce2cf27c5root 40383827f40a2d97261528087331b0bee6ce2cf27c5root arg.req.size = size; 40483827f40a2d97261528087331b0bee6ce2cf27c5root arg.req.placement = slabPool->proposedPlacement; 40583827f40a2d97261528087331b0bee6ce2cf27c5root arg.req.page_alignment = slabPool->pageAlignment; 40683827f40a2d97261528087331b0bee6ce2cf27c5root 40783827f40a2d97261528087331b0bee6ce2cf27c5root DRMRESTARTCOMMANDWRITEREAD(slabPool->pool.fd, 40883827f40a2d97261528087331b0bee6ce2cf27c5root slabPool->devOffset + TTM_PL_CREATE, 40983827f40a2d97261528087331b0bee6ce2cf27c5root arg, ret); 41083827f40a2d97261528087331b0bee6ce2cf27c5root if (ret) 41183827f40a2d97261528087331b0bee6ce2cf27c5root goto out_err0; 41283827f40a2d97261528087331b0bee6ce2cf27c5root 41383827f40a2d97261528087331b0bee6ce2cf27c5root kbo->kBuf.gpuOffset = arg.rep.gpu_offset; 41483827f40a2d97261528087331b0bee6ce2cf27c5root kbo->kBuf.placement = arg.rep.placement; 41583827f40a2d97261528087331b0bee6ce2cf27c5root kbo->kBuf.handle = arg.rep.handle; 41683827f40a2d97261528087331b0bee6ce2cf27c5root 41783827f40a2d97261528087331b0bee6ce2cf27c5root kbo->actualSize = arg.rep.bo_size; 41883827f40a2d97261528087331b0bee6ce2cf27c5root kbo->mapHandle = arg.rep.map_handle; 41983827f40a2d97261528087331b0bee6ce2cf27c5root kbo->proposedPlacement = slabPool->proposedPlacement; 42083827f40a2d97261528087331b0bee6ce2cf27c5root } 42183827f40a2d97261528087331b0bee6ce2cf27c5root 42283827f40a2d97261528087331b0bee6ce2cf27c5root kbo->virtual = mmap(0, kbo->actualSize, 42383827f40a2d97261528087331b0bee6ce2cf27c5root PROT_READ | PROT_WRITE, MAP_SHARED, 42483827f40a2d97261528087331b0bee6ce2cf27c5root slabPool->pool.fd, kbo->mapHandle); 42583827f40a2d97261528087331b0bee6ce2cf27c5root 42683827f40a2d97261528087331b0bee6ce2cf27c5root if (kbo->virtual == MAP_FAILED) { 42783827f40a2d97261528087331b0bee6ce2cf27c5root ret = -errno; 42883827f40a2d97261528087331b0bee6ce2cf27c5root goto out_err1; 42983827f40a2d97261528087331b0bee6ce2cf27c5root } 43083827f40a2d97261528087331b0bee6ce2cf27c5root 43183827f40a2d97261528087331b0bee6ce2cf27c5root return kbo; 43283827f40a2d97261528087331b0bee6ce2cf27c5root 43383827f40a2d97261528087331b0bee6ce2cf27c5root out_err1: 43483827f40a2d97261528087331b0bee6ce2cf27c5root { 43583827f40a2d97261528087331b0bee6ce2cf27c5root struct ttm_pl_reference_req arg = {.handle = kbo->kBuf.handle }; 43683827f40a2d97261528087331b0bee6ce2cf27c5root 43783827f40a2d97261528087331b0bee6ce2cf27c5root (void)drmCommandWrite(slabPool->pool.fd, 43883827f40a2d97261528087331b0bee6ce2cf27c5root slabPool->devOffset + TTM_PL_UNREF, 43983827f40a2d97261528087331b0bee6ce2cf27c5root &arg, sizeof(arg)); 44083827f40a2d97261528087331b0bee6ce2cf27c5root } 44183827f40a2d97261528087331b0bee6ce2cf27c5root out_err0: 44283827f40a2d97261528087331b0bee6ce2cf27c5root free(kbo); 44383827f40a2d97261528087331b0bee6ce2cf27c5root return NULL; 44483827f40a2d97261528087331b0bee6ce2cf27c5root} 44583827f40a2d97261528087331b0bee6ce2cf27c5root 44683827f40a2d97261528087331b0bee6ce2cf27c5rootstatic int 44783827f40a2d97261528087331b0bee6ce2cf27c5rootwsbmAllocSlab(struct _WsbmSlabSizeHeader *header) 44883827f40a2d97261528087331b0bee6ce2cf27c5root{ 44983827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmSlab *slab; 45083827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmSlabBuffer *sBuf; 45183827f40a2d97261528087331b0bee6ce2cf27c5root uint32_t numBuffers; 4523795b36d0c937666a5bddc352c781d5e0beec26bThierry Strudel uint32_t ret; 4533795b36d0c937666a5bddc352c781d5e0beec26bThierry Strudel uint32_t i; 45483827f40a2d97261528087331b0bee6ce2cf27c5root 45583827f40a2d97261528087331b0bee6ce2cf27c5root slab = calloc(1, sizeof(*slab)); 45683827f40a2d97261528087331b0bee6ce2cf27c5root if (!slab) 45783827f40a2d97261528087331b0bee6ce2cf27c5root return -ENOMEM; 45883827f40a2d97261528087331b0bee6ce2cf27c5root 45983827f40a2d97261528087331b0bee6ce2cf27c5root slab->kbo = wsbmAllocKernelBO(header); 46083827f40a2d97261528087331b0bee6ce2cf27c5root if (!slab->kbo) { 46183827f40a2d97261528087331b0bee6ce2cf27c5root ret = -ENOMEM; 46283827f40a2d97261528087331b0bee6ce2cf27c5root goto out_err0; 46383827f40a2d97261528087331b0bee6ce2cf27c5root } 46483827f40a2d97261528087331b0bee6ce2cf27c5root 46583827f40a2d97261528087331b0bee6ce2cf27c5root numBuffers = slab->kbo->actualSize / header->bufSize; 466ba6cd22cc9dbadb14dad331ef6ddc8b1e403a654Austin Hu if (!numBuffers) { 467ba6cd22cc9dbadb14dad331ef6ddc8b1e403a654Austin Hu ret = -ENOMEM; 468ba6cd22cc9dbadb14dad331ef6ddc8b1e403a654Austin Hu goto out_err1; 469ba6cd22cc9dbadb14dad331ef6ddc8b1e403a654Austin Hu } 47083827f40a2d97261528087331b0bee6ce2cf27c5root 47183827f40a2d97261528087331b0bee6ce2cf27c5root slab->buffers = calloc(numBuffers, sizeof(*slab->buffers)); 47283827f40a2d97261528087331b0bee6ce2cf27c5root if (!slab->buffers) { 47383827f40a2d97261528087331b0bee6ce2cf27c5root ret = -ENOMEM; 47483827f40a2d97261528087331b0bee6ce2cf27c5root goto out_err1; 47583827f40a2d97261528087331b0bee6ce2cf27c5root } 47683827f40a2d97261528087331b0bee6ce2cf27c5root 47783827f40a2d97261528087331b0bee6ce2cf27c5root WSBMINITLISTHEAD(&slab->head); 47883827f40a2d97261528087331b0bee6ce2cf27c5root WSBMINITLISTHEAD(&slab->freeBuffers); 47983827f40a2d97261528087331b0bee6ce2cf27c5root slab->numBuffers = numBuffers; 48083827f40a2d97261528087331b0bee6ce2cf27c5root slab->numFree = 0; 48183827f40a2d97261528087331b0bee6ce2cf27c5root slab->header = header; 48283827f40a2d97261528087331b0bee6ce2cf27c5root 48383827f40a2d97261528087331b0bee6ce2cf27c5root sBuf = slab->buffers; 48483827f40a2d97261528087331b0bee6ce2cf27c5root for (i = 0; i < numBuffers; ++i) { 48583827f40a2d97261528087331b0bee6ce2cf27c5root ret = wsbmBufStorageInit(&sBuf->storage, &header->slabPool->pool); 48683827f40a2d97261528087331b0bee6ce2cf27c5root if (ret) 48783827f40a2d97261528087331b0bee6ce2cf27c5root goto out_err2; 48883827f40a2d97261528087331b0bee6ce2cf27c5root sBuf->parent = slab; 48983827f40a2d97261528087331b0bee6ce2cf27c5root sBuf->start = i * header->bufSize; 49083827f40a2d97261528087331b0bee6ce2cf27c5root sBuf->virtual = (void *)((uint8_t *) slab->kbo->virtual + 49183827f40a2d97261528087331b0bee6ce2cf27c5root sBuf->start); 49283827f40a2d97261528087331b0bee6ce2cf27c5root wsbmAtomicSet(&sBuf->writers, 0); 49383827f40a2d97261528087331b0bee6ce2cf27c5root sBuf->isSlabBuffer = 1; 49483827f40a2d97261528087331b0bee6ce2cf27c5root WSBM_COND_INIT(&sBuf->event); 49583827f40a2d97261528087331b0bee6ce2cf27c5root WSBMLISTADDTAIL(&sBuf->head, &slab->freeBuffers); 49683827f40a2d97261528087331b0bee6ce2cf27c5root slab->numFree++; 49783827f40a2d97261528087331b0bee6ce2cf27c5root sBuf++; 49883827f40a2d97261528087331b0bee6ce2cf27c5root } 49983827f40a2d97261528087331b0bee6ce2cf27c5root 50083827f40a2d97261528087331b0bee6ce2cf27c5root WSBMLISTADDTAIL(&slab->head, &header->slabs); 50183827f40a2d97261528087331b0bee6ce2cf27c5root 50283827f40a2d97261528087331b0bee6ce2cf27c5root return 0; 50383827f40a2d97261528087331b0bee6ce2cf27c5root 50483827f40a2d97261528087331b0bee6ce2cf27c5root out_err2: 50583827f40a2d97261528087331b0bee6ce2cf27c5root sBuf = slab->buffers; 50683827f40a2d97261528087331b0bee6ce2cf27c5root for (i = 0; i < numBuffers; ++i) { 50783827f40a2d97261528087331b0bee6ce2cf27c5root if (sBuf->parent == slab) { 50883827f40a2d97261528087331b0bee6ce2cf27c5root WSBM_COND_FREE(&sBuf->event); 50983827f40a2d97261528087331b0bee6ce2cf27c5root wsbmBufStorageTakedown(&sBuf->storage); 51083827f40a2d97261528087331b0bee6ce2cf27c5root } 51183827f40a2d97261528087331b0bee6ce2cf27c5root sBuf++; 51283827f40a2d97261528087331b0bee6ce2cf27c5root } 51383827f40a2d97261528087331b0bee6ce2cf27c5root free(slab->buffers); 51483827f40a2d97261528087331b0bee6ce2cf27c5root out_err1: 51583827f40a2d97261528087331b0bee6ce2cf27c5root wsbmSetKernelBOFree(header->slabPool->cache, slab->kbo); 51683827f40a2d97261528087331b0bee6ce2cf27c5root out_err0: 51783827f40a2d97261528087331b0bee6ce2cf27c5root free(slab); 51883827f40a2d97261528087331b0bee6ce2cf27c5root return ret; 51983827f40a2d97261528087331b0bee6ce2cf27c5root} 52083827f40a2d97261528087331b0bee6ce2cf27c5root 52183827f40a2d97261528087331b0bee6ce2cf27c5root/* 52283827f40a2d97261528087331b0bee6ce2cf27c5root * Delete a buffer from the slab header delayed list and put 52383827f40a2d97261528087331b0bee6ce2cf27c5root * it on the slab free list. 52483827f40a2d97261528087331b0bee6ce2cf27c5root */ 52583827f40a2d97261528087331b0bee6ce2cf27c5root 52683827f40a2d97261528087331b0bee6ce2cf27c5rootstatic void 52783827f40a2d97261528087331b0bee6ce2cf27c5rootwsbmSlabFreeBufferLocked(struct _WsbmSlabBuffer *buf) 52883827f40a2d97261528087331b0bee6ce2cf27c5root{ 52983827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmSlab *slab = buf->parent; 53083827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmSlabSizeHeader *header = slab->header; 53183827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmListHead *list = &buf->head; 53283827f40a2d97261528087331b0bee6ce2cf27c5root 53383827f40a2d97261528087331b0bee6ce2cf27c5root WSBMLISTDEL(list); 53483827f40a2d97261528087331b0bee6ce2cf27c5root WSBMLISTADDTAIL(list, &slab->freeBuffers); 53583827f40a2d97261528087331b0bee6ce2cf27c5root slab->numFree++; 53683827f40a2d97261528087331b0bee6ce2cf27c5root 53783827f40a2d97261528087331b0bee6ce2cf27c5root if (slab->head.next == &slab->head) 53883827f40a2d97261528087331b0bee6ce2cf27c5root WSBMLISTADDTAIL(&slab->head, &header->slabs); 53983827f40a2d97261528087331b0bee6ce2cf27c5root 54083827f40a2d97261528087331b0bee6ce2cf27c5root if (slab->numFree == slab->numBuffers) { 54183827f40a2d97261528087331b0bee6ce2cf27c5root list = &slab->head; 54283827f40a2d97261528087331b0bee6ce2cf27c5root WSBMLISTDEL(list); 54383827f40a2d97261528087331b0bee6ce2cf27c5root WSBMLISTADDTAIL(list, &header->freeSlabs); 54483827f40a2d97261528087331b0bee6ce2cf27c5root } 54583827f40a2d97261528087331b0bee6ce2cf27c5root 54683827f40a2d97261528087331b0bee6ce2cf27c5root if (header->slabs.next == &header->slabs || 54783827f40a2d97261528087331b0bee6ce2cf27c5root slab->numFree != slab->numBuffers) { 54883827f40a2d97261528087331b0bee6ce2cf27c5root 54983827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmListHead *next; 55083827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmSlabCache *cache = header->slabPool->cache; 55183827f40a2d97261528087331b0bee6ce2cf27c5root 55283827f40a2d97261528087331b0bee6ce2cf27c5root WSBMLISTFOREACHSAFE(list, next, &header->freeSlabs) { 5533795b36d0c937666a5bddc352c781d5e0beec26bThierry Strudel uint32_t i; 55483827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmSlabBuffer *sBuf; 55583827f40a2d97261528087331b0bee6ce2cf27c5root 55683827f40a2d97261528087331b0bee6ce2cf27c5root slab = WSBMLISTENTRY(list, struct _WsbmSlab, head); 55783827f40a2d97261528087331b0bee6ce2cf27c5root 55883827f40a2d97261528087331b0bee6ce2cf27c5root WSBMLISTDELINIT(list); 55983827f40a2d97261528087331b0bee6ce2cf27c5root 56083827f40a2d97261528087331b0bee6ce2cf27c5root sBuf = slab->buffers; 56183827f40a2d97261528087331b0bee6ce2cf27c5root for (i = 0; i < slab->numBuffers; ++i) { 56283827f40a2d97261528087331b0bee6ce2cf27c5root if (sBuf->parent == slab) { 56383827f40a2d97261528087331b0bee6ce2cf27c5root WSBM_COND_FREE(&sBuf->event); 56483827f40a2d97261528087331b0bee6ce2cf27c5root wsbmBufStorageTakedown(&sBuf->storage); 56583827f40a2d97261528087331b0bee6ce2cf27c5root } 56683827f40a2d97261528087331b0bee6ce2cf27c5root sBuf++; 56783827f40a2d97261528087331b0bee6ce2cf27c5root } 56883827f40a2d97261528087331b0bee6ce2cf27c5root wsbmSetKernelBOFree(cache, slab->kbo); 56983827f40a2d97261528087331b0bee6ce2cf27c5root free(slab->buffers); 57083827f40a2d97261528087331b0bee6ce2cf27c5root free(slab); 57183827f40a2d97261528087331b0bee6ce2cf27c5root } 57283827f40a2d97261528087331b0bee6ce2cf27c5root } 57383827f40a2d97261528087331b0bee6ce2cf27c5root} 57483827f40a2d97261528087331b0bee6ce2cf27c5root 57583827f40a2d97261528087331b0bee6ce2cf27c5rootstatic void 57683827f40a2d97261528087331b0bee6ce2cf27c5rootwsbmSlabCheckFreeLocked(struct _WsbmSlabSizeHeader *header, int wait) 57783827f40a2d97261528087331b0bee6ce2cf27c5root{ 57883827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmListHead *list, *prev, *first, *head; 57983827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmSlabBuffer *sBuf; 58083827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmSlab *slab; 58183827f40a2d97261528087331b0bee6ce2cf27c5root int firstWasSignaled = 1; 58283827f40a2d97261528087331b0bee6ce2cf27c5root int signaled; 5833795b36d0c937666a5bddc352c781d5e0beec26bThierry Strudel uint32_t i; 58483827f40a2d97261528087331b0bee6ce2cf27c5root int ret; 58583827f40a2d97261528087331b0bee6ce2cf27c5root 58683827f40a2d97261528087331b0bee6ce2cf27c5root /* 58783827f40a2d97261528087331b0bee6ce2cf27c5root * Rerun the freeing test if the youngest tested buffer 58883827f40a2d97261528087331b0bee6ce2cf27c5root * was signaled, since there might be more idle buffers 58983827f40a2d97261528087331b0bee6ce2cf27c5root * in the delay list. 59083827f40a2d97261528087331b0bee6ce2cf27c5root */ 59183827f40a2d97261528087331b0bee6ce2cf27c5root 59283827f40a2d97261528087331b0bee6ce2cf27c5root while (firstWasSignaled) { 59383827f40a2d97261528087331b0bee6ce2cf27c5root firstWasSignaled = 0; 59483827f40a2d97261528087331b0bee6ce2cf27c5root signaled = 0; 59583827f40a2d97261528087331b0bee6ce2cf27c5root first = header->delayedBuffers.next; 59683827f40a2d97261528087331b0bee6ce2cf27c5root 59783827f40a2d97261528087331b0bee6ce2cf27c5root /* Only examine the oldest 1/3 of delayed buffers: 59883827f40a2d97261528087331b0bee6ce2cf27c5root */ 59983827f40a2d97261528087331b0bee6ce2cf27c5root if (header->numDelayed > 3) { 60083827f40a2d97261528087331b0bee6ce2cf27c5root for (i = 0; i < header->numDelayed; i += 3) { 60183827f40a2d97261528087331b0bee6ce2cf27c5root first = first->next; 60283827f40a2d97261528087331b0bee6ce2cf27c5root } 60383827f40a2d97261528087331b0bee6ce2cf27c5root } 60483827f40a2d97261528087331b0bee6ce2cf27c5root 60583827f40a2d97261528087331b0bee6ce2cf27c5root /* 60683827f40a2d97261528087331b0bee6ce2cf27c5root * No need to take the buffer mutex for each buffer we loop 60783827f40a2d97261528087331b0bee6ce2cf27c5root * through since we're currently the only user. 60883827f40a2d97261528087331b0bee6ce2cf27c5root */ 60983827f40a2d97261528087331b0bee6ce2cf27c5root 61083827f40a2d97261528087331b0bee6ce2cf27c5root head = first->next; 61183827f40a2d97261528087331b0bee6ce2cf27c5root WSBMLISTFOREACHPREVSAFE(list, prev, head) { 61283827f40a2d97261528087331b0bee6ce2cf27c5root 61383827f40a2d97261528087331b0bee6ce2cf27c5root if (list == &header->delayedBuffers) 61483827f40a2d97261528087331b0bee6ce2cf27c5root break; 61583827f40a2d97261528087331b0bee6ce2cf27c5root 61683827f40a2d97261528087331b0bee6ce2cf27c5root sBuf = WSBMLISTENTRY(list, struct _WsbmSlabBuffer, head); 61783827f40a2d97261528087331b0bee6ce2cf27c5root 61883827f40a2d97261528087331b0bee6ce2cf27c5root slab = sBuf->parent; 61983827f40a2d97261528087331b0bee6ce2cf27c5root 62083827f40a2d97261528087331b0bee6ce2cf27c5root if (!signaled) { 62183827f40a2d97261528087331b0bee6ce2cf27c5root if (wait) { 62283827f40a2d97261528087331b0bee6ce2cf27c5root ret = wsbmFenceFinish(sBuf->fence, sBuf->fenceType, 0); 62383827f40a2d97261528087331b0bee6ce2cf27c5root if (ret) 62483827f40a2d97261528087331b0bee6ce2cf27c5root break; 62583827f40a2d97261528087331b0bee6ce2cf27c5root signaled = 1; 62683827f40a2d97261528087331b0bee6ce2cf27c5root wait = 0; 62783827f40a2d97261528087331b0bee6ce2cf27c5root } else { 62883827f40a2d97261528087331b0bee6ce2cf27c5root signaled = 62983827f40a2d97261528087331b0bee6ce2cf27c5root wsbmFenceSignaled(sBuf->fence, sBuf->fenceType); 63083827f40a2d97261528087331b0bee6ce2cf27c5root#ifdef DEBUG_FENCESIGNALED 63183827f40a2d97261528087331b0bee6ce2cf27c5root fencesignaled++; 63283827f40a2d97261528087331b0bee6ce2cf27c5root#endif 63383827f40a2d97261528087331b0bee6ce2cf27c5root } 63483827f40a2d97261528087331b0bee6ce2cf27c5root if (signaled) { 63583827f40a2d97261528087331b0bee6ce2cf27c5root if (list == first) 63683827f40a2d97261528087331b0bee6ce2cf27c5root firstWasSignaled = 1; 63783827f40a2d97261528087331b0bee6ce2cf27c5root wsbmFenceUnreference(&sBuf->fence); 63883827f40a2d97261528087331b0bee6ce2cf27c5root header->numDelayed--; 63983827f40a2d97261528087331b0bee6ce2cf27c5root wsbmSlabFreeBufferLocked(sBuf); 64083827f40a2d97261528087331b0bee6ce2cf27c5root } else 64183827f40a2d97261528087331b0bee6ce2cf27c5root break; 64283827f40a2d97261528087331b0bee6ce2cf27c5root } else if (wsbmFenceSignaledCached(sBuf->fence, sBuf->fenceType)) { 64383827f40a2d97261528087331b0bee6ce2cf27c5root wsbmFenceUnreference(&sBuf->fence); 64483827f40a2d97261528087331b0bee6ce2cf27c5root header->numDelayed--; 64583827f40a2d97261528087331b0bee6ce2cf27c5root wsbmSlabFreeBufferLocked(sBuf); 64683827f40a2d97261528087331b0bee6ce2cf27c5root } 64783827f40a2d97261528087331b0bee6ce2cf27c5root } 64883827f40a2d97261528087331b0bee6ce2cf27c5root } 64983827f40a2d97261528087331b0bee6ce2cf27c5root} 65083827f40a2d97261528087331b0bee6ce2cf27c5root 65183827f40a2d97261528087331b0bee6ce2cf27c5rootstatic struct _WsbmSlabBuffer * 65283827f40a2d97261528087331b0bee6ce2cf27c5rootwsbmSlabAllocBuffer(struct _WsbmSlabSizeHeader *header) 65383827f40a2d97261528087331b0bee6ce2cf27c5root{ 65483827f40a2d97261528087331b0bee6ce2cf27c5root static struct _WsbmSlabBuffer *buf; 65583827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmSlab *slab; 65683827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmListHead *list; 65783827f40a2d97261528087331b0bee6ce2cf27c5root int count = WSBM_SLABPOOL_ALLOC_RETRIES; 65883827f40a2d97261528087331b0bee6ce2cf27c5root 65983827f40a2d97261528087331b0bee6ce2cf27c5root WSBM_MUTEX_LOCK(&header->mutex); 66083827f40a2d97261528087331b0bee6ce2cf27c5root while (header->slabs.next == &header->slabs && count > 0) { 66183827f40a2d97261528087331b0bee6ce2cf27c5root wsbmSlabCheckFreeLocked(header, 0); 66283827f40a2d97261528087331b0bee6ce2cf27c5root if (header->slabs.next != &header->slabs) 66383827f40a2d97261528087331b0bee6ce2cf27c5root break; 66483827f40a2d97261528087331b0bee6ce2cf27c5root 66583827f40a2d97261528087331b0bee6ce2cf27c5root WSBM_MUTEX_UNLOCK(&header->mutex); 66683827f40a2d97261528087331b0bee6ce2cf27c5root if (count != WSBM_SLABPOOL_ALLOC_RETRIES) 66783827f40a2d97261528087331b0bee6ce2cf27c5root usleep(1000); 66883827f40a2d97261528087331b0bee6ce2cf27c5root WSBM_MUTEX_LOCK(&header->mutex); 66983827f40a2d97261528087331b0bee6ce2cf27c5root (void)wsbmAllocSlab(header); 67083827f40a2d97261528087331b0bee6ce2cf27c5root count--; 67183827f40a2d97261528087331b0bee6ce2cf27c5root } 67283827f40a2d97261528087331b0bee6ce2cf27c5root 67383827f40a2d97261528087331b0bee6ce2cf27c5root list = header->slabs.next; 67483827f40a2d97261528087331b0bee6ce2cf27c5root if (list == &header->slabs) { 67583827f40a2d97261528087331b0bee6ce2cf27c5root WSBM_MUTEX_UNLOCK(&header->mutex); 67683827f40a2d97261528087331b0bee6ce2cf27c5root return NULL; 67783827f40a2d97261528087331b0bee6ce2cf27c5root } 67883827f40a2d97261528087331b0bee6ce2cf27c5root slab = WSBMLISTENTRY(list, struct _WsbmSlab, head); 67983827f40a2d97261528087331b0bee6ce2cf27c5root if (--slab->numFree == 0) 68083827f40a2d97261528087331b0bee6ce2cf27c5root WSBMLISTDELINIT(list); 68183827f40a2d97261528087331b0bee6ce2cf27c5root 68283827f40a2d97261528087331b0bee6ce2cf27c5root list = slab->freeBuffers.next; 68383827f40a2d97261528087331b0bee6ce2cf27c5root WSBMLISTDELINIT(list); 68483827f40a2d97261528087331b0bee6ce2cf27c5root 68583827f40a2d97261528087331b0bee6ce2cf27c5root WSBM_MUTEX_UNLOCK(&header->mutex); 68683827f40a2d97261528087331b0bee6ce2cf27c5root buf = WSBMLISTENTRY(list, struct _WsbmSlabBuffer, head); 68783827f40a2d97261528087331b0bee6ce2cf27c5root 68883827f40a2d97261528087331b0bee6ce2cf27c5root buf->storage.destroyContainer = NULL; 68983827f40a2d97261528087331b0bee6ce2cf27c5root 69083827f40a2d97261528087331b0bee6ce2cf27c5root#ifdef DEBUG_FENCESIGNALED 69183827f40a2d97261528087331b0bee6ce2cf27c5root createbuffer++; 69283827f40a2d97261528087331b0bee6ce2cf27c5root#endif 69383827f40a2d97261528087331b0bee6ce2cf27c5root return buf; 69483827f40a2d97261528087331b0bee6ce2cf27c5root} 69583827f40a2d97261528087331b0bee6ce2cf27c5root 69683827f40a2d97261528087331b0bee6ce2cf27c5rootstatic struct _WsbmBufStorage * 69783827f40a2d97261528087331b0bee6ce2cf27c5rootpool_create(struct _WsbmBufferPool *pool, unsigned long size, 69883827f40a2d97261528087331b0bee6ce2cf27c5root uint32_t placement, unsigned alignment) 69983827f40a2d97261528087331b0bee6ce2cf27c5root{ 70083827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmSlabPool *slabPool = slabPoolFromPool(pool); 70183827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmSlabSizeHeader *header; 70283827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmSlabBuffer *sBuf; 7033795b36d0c937666a5bddc352c781d5e0beec26bThierry Strudel uint32_t i; 70483827f40a2d97261528087331b0bee6ce2cf27c5root int ret; 70583827f40a2d97261528087331b0bee6ce2cf27c5root 70683827f40a2d97261528087331b0bee6ce2cf27c5root /* 70783827f40a2d97261528087331b0bee6ce2cf27c5root * FIXME: Check for compatibility. 70883827f40a2d97261528087331b0bee6ce2cf27c5root */ 70983827f40a2d97261528087331b0bee6ce2cf27c5root 71083827f40a2d97261528087331b0bee6ce2cf27c5root header = slabPool->headers; 71183827f40a2d97261528087331b0bee6ce2cf27c5root for (i = 0; i < slabPool->numBuckets; ++i) { 71283827f40a2d97261528087331b0bee6ce2cf27c5root if (header->bufSize >= size) 71383827f40a2d97261528087331b0bee6ce2cf27c5root break; 71483827f40a2d97261528087331b0bee6ce2cf27c5root header++; 71583827f40a2d97261528087331b0bee6ce2cf27c5root } 71683827f40a2d97261528087331b0bee6ce2cf27c5root 71783827f40a2d97261528087331b0bee6ce2cf27c5root if (i < slabPool->numBuckets) { 71883827f40a2d97261528087331b0bee6ce2cf27c5root sBuf = wsbmSlabAllocBuffer(header); 71983827f40a2d97261528087331b0bee6ce2cf27c5root return ((sBuf) ? &sBuf->storage : NULL); 72083827f40a2d97261528087331b0bee6ce2cf27c5root } 72183827f40a2d97261528087331b0bee6ce2cf27c5root 72283827f40a2d97261528087331b0bee6ce2cf27c5root /* 72383827f40a2d97261528087331b0bee6ce2cf27c5root * Fall back to allocate a buffer object directly from DRM. 72483827f40a2d97261528087331b0bee6ce2cf27c5root * and wrap it in a wsbmBO structure. 72583827f40a2d97261528087331b0bee6ce2cf27c5root */ 72683827f40a2d97261528087331b0bee6ce2cf27c5root 72783827f40a2d97261528087331b0bee6ce2cf27c5root sBuf = calloc(1, sizeof(*sBuf)); 72883827f40a2d97261528087331b0bee6ce2cf27c5root 72983827f40a2d97261528087331b0bee6ce2cf27c5root if (!sBuf) 73083827f40a2d97261528087331b0bee6ce2cf27c5root return NULL; 73183827f40a2d97261528087331b0bee6ce2cf27c5root 73283827f40a2d97261528087331b0bee6ce2cf27c5root if (alignment) { 73383827f40a2d97261528087331b0bee6ce2cf27c5root if ((alignment < slabPool->pageSize) 73483827f40a2d97261528087331b0bee6ce2cf27c5root && (slabPool->pageSize % alignment)) 73583827f40a2d97261528087331b0bee6ce2cf27c5root goto out_err0; 73683827f40a2d97261528087331b0bee6ce2cf27c5root if ((alignment > slabPool->pageSize) 73783827f40a2d97261528087331b0bee6ce2cf27c5root && (alignment % slabPool->pageSize)) 73883827f40a2d97261528087331b0bee6ce2cf27c5root goto out_err0; 73983827f40a2d97261528087331b0bee6ce2cf27c5root } 74083827f40a2d97261528087331b0bee6ce2cf27c5root 74183827f40a2d97261528087331b0bee6ce2cf27c5root ret = wsbmBufStorageInit(&sBuf->storage, pool); 74283827f40a2d97261528087331b0bee6ce2cf27c5root if (ret) 74383827f40a2d97261528087331b0bee6ce2cf27c5root goto out_err0; 74483827f40a2d97261528087331b0bee6ce2cf27c5root 74583827f40a2d97261528087331b0bee6ce2cf27c5root ret = WSBM_COND_INIT(&sBuf->event); 74683827f40a2d97261528087331b0bee6ce2cf27c5root if (ret) 74783827f40a2d97261528087331b0bee6ce2cf27c5root goto out_err1; 74883827f40a2d97261528087331b0bee6ce2cf27c5root 74983827f40a2d97261528087331b0bee6ce2cf27c5root { 75083827f40a2d97261528087331b0bee6ce2cf27c5root union ttm_pl_create_arg arg; 75183827f40a2d97261528087331b0bee6ce2cf27c5root 75283827f40a2d97261528087331b0bee6ce2cf27c5root arg.req.size = size; 75383827f40a2d97261528087331b0bee6ce2cf27c5root arg.req.placement = placement; 75483827f40a2d97261528087331b0bee6ce2cf27c5root arg.req.page_alignment = alignment / slabPool->pageSize; 75583827f40a2d97261528087331b0bee6ce2cf27c5root 75683827f40a2d97261528087331b0bee6ce2cf27c5root DRMRESTARTCOMMANDWRITEREAD(pool->fd, 75783827f40a2d97261528087331b0bee6ce2cf27c5root slabPool->devOffset + TTM_PL_CREATE, 75883827f40a2d97261528087331b0bee6ce2cf27c5root arg, ret); 75983827f40a2d97261528087331b0bee6ce2cf27c5root 76083827f40a2d97261528087331b0bee6ce2cf27c5root if (ret) 76183827f40a2d97261528087331b0bee6ce2cf27c5root goto out_err2; 76283827f40a2d97261528087331b0bee6ce2cf27c5root 76383827f40a2d97261528087331b0bee6ce2cf27c5root sBuf->kBuf.gpuOffset = arg.rep.gpu_offset; 76483827f40a2d97261528087331b0bee6ce2cf27c5root sBuf->kBuf.placement = arg.rep.placement; 76583827f40a2d97261528087331b0bee6ce2cf27c5root sBuf->kBuf.handle = arg.rep.handle; 76683827f40a2d97261528087331b0bee6ce2cf27c5root sBuf->mapHandle = arg.rep.map_handle; 76783827f40a2d97261528087331b0bee6ce2cf27c5root sBuf->requestedSize = size; 76883827f40a2d97261528087331b0bee6ce2cf27c5root 76983827f40a2d97261528087331b0bee6ce2cf27c5root sBuf->virtual = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, 77083827f40a2d97261528087331b0bee6ce2cf27c5root pool->fd, sBuf->mapHandle); 77183827f40a2d97261528087331b0bee6ce2cf27c5root 77283827f40a2d97261528087331b0bee6ce2cf27c5root if (sBuf->virtual == MAP_FAILED) 77383827f40a2d97261528087331b0bee6ce2cf27c5root goto out_err3; 77483827f40a2d97261528087331b0bee6ce2cf27c5root } 77583827f40a2d97261528087331b0bee6ce2cf27c5root 77683827f40a2d97261528087331b0bee6ce2cf27c5root wsbmAtomicSet(&sBuf->writers, 0); 77783827f40a2d97261528087331b0bee6ce2cf27c5root return &sBuf->storage; 77883827f40a2d97261528087331b0bee6ce2cf27c5root out_err3: 77983827f40a2d97261528087331b0bee6ce2cf27c5root { 78083827f40a2d97261528087331b0bee6ce2cf27c5root struct ttm_pl_reference_req arg; 78183827f40a2d97261528087331b0bee6ce2cf27c5root 78283827f40a2d97261528087331b0bee6ce2cf27c5root arg.handle = sBuf->kBuf.handle; 78383827f40a2d97261528087331b0bee6ce2cf27c5root (void)drmCommandWriteRead(pool->fd, 78483827f40a2d97261528087331b0bee6ce2cf27c5root slabPool->devOffset + TTM_PL_UNREF, 78583827f40a2d97261528087331b0bee6ce2cf27c5root &arg, sizeof(arg)); 78683827f40a2d97261528087331b0bee6ce2cf27c5root } 78783827f40a2d97261528087331b0bee6ce2cf27c5root out_err2: 78883827f40a2d97261528087331b0bee6ce2cf27c5root WSBM_COND_FREE(&sBuf->event); 78983827f40a2d97261528087331b0bee6ce2cf27c5root out_err1: 79083827f40a2d97261528087331b0bee6ce2cf27c5root wsbmBufStorageTakedown(&sBuf->storage); 79183827f40a2d97261528087331b0bee6ce2cf27c5root out_err0: 79283827f40a2d97261528087331b0bee6ce2cf27c5root free(sBuf); 79383827f40a2d97261528087331b0bee6ce2cf27c5root return NULL; 79483827f40a2d97261528087331b0bee6ce2cf27c5root} 79583827f40a2d97261528087331b0bee6ce2cf27c5root 79683827f40a2d97261528087331b0bee6ce2cf27c5rootstatic void 79783827f40a2d97261528087331b0bee6ce2cf27c5rootpool_destroy(struct _WsbmBufStorage **p_buf) 79883827f40a2d97261528087331b0bee6ce2cf27c5root{ 79983827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmBufStorage *buf = *p_buf; 80083827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmSlabBuffer *sBuf = slabBuffer(buf); 80183827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmSlab *slab; 80283827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmSlabSizeHeader *header; 80383827f40a2d97261528087331b0bee6ce2cf27c5root 80483827f40a2d97261528087331b0bee6ce2cf27c5root *p_buf = NULL; 80583827f40a2d97261528087331b0bee6ce2cf27c5root 80683827f40a2d97261528087331b0bee6ce2cf27c5root if (!sBuf->isSlabBuffer) { 80783827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmSlabPool *slabPool = slabPoolFromBuf(sBuf); 80883827f40a2d97261528087331b0bee6ce2cf27c5root struct ttm_pl_reference_req arg; 80983827f40a2d97261528087331b0bee6ce2cf27c5root 81083827f40a2d97261528087331b0bee6ce2cf27c5root if (sBuf->virtual != NULL) { 81183827f40a2d97261528087331b0bee6ce2cf27c5root (void)munmap(sBuf->virtual, sBuf->requestedSize); 81283827f40a2d97261528087331b0bee6ce2cf27c5root sBuf->virtual = NULL; 81383827f40a2d97261528087331b0bee6ce2cf27c5root } 81483827f40a2d97261528087331b0bee6ce2cf27c5root 81583827f40a2d97261528087331b0bee6ce2cf27c5root arg.handle = sBuf->kBuf.handle; 81683827f40a2d97261528087331b0bee6ce2cf27c5root (void)drmCommandWrite(slabPool->pool.fd, 81783827f40a2d97261528087331b0bee6ce2cf27c5root slabPool->devOffset + TTM_PL_UNREF, 81883827f40a2d97261528087331b0bee6ce2cf27c5root &arg, sizeof(arg)); 81983827f40a2d97261528087331b0bee6ce2cf27c5root 82083827f40a2d97261528087331b0bee6ce2cf27c5root WSBM_COND_FREE(&sBuf->event); 82183827f40a2d97261528087331b0bee6ce2cf27c5root wsbmBufStorageTakedown(&sBuf->storage); 82283827f40a2d97261528087331b0bee6ce2cf27c5root free(sBuf); 82383827f40a2d97261528087331b0bee6ce2cf27c5root return; 82483827f40a2d97261528087331b0bee6ce2cf27c5root } 82583827f40a2d97261528087331b0bee6ce2cf27c5root 82683827f40a2d97261528087331b0bee6ce2cf27c5root slab = sBuf->parent; 82783827f40a2d97261528087331b0bee6ce2cf27c5root header = slab->header; 82883827f40a2d97261528087331b0bee6ce2cf27c5root 82983827f40a2d97261528087331b0bee6ce2cf27c5root /* 83083827f40a2d97261528087331b0bee6ce2cf27c5root * No need to take the buffer mutex below since we're the only user. 83183827f40a2d97261528087331b0bee6ce2cf27c5root */ 83283827f40a2d97261528087331b0bee6ce2cf27c5root 83383827f40a2d97261528087331b0bee6ce2cf27c5root WSBM_MUTEX_LOCK(&header->mutex); 83483827f40a2d97261528087331b0bee6ce2cf27c5root sBuf->unFenced = 0; 83583827f40a2d97261528087331b0bee6ce2cf27c5root wsbmAtomicSet(&sBuf->writers, 0); 83683827f40a2d97261528087331b0bee6ce2cf27c5root wsbmAtomicSet(&sBuf->storage.refCount, 1); 83783827f40a2d97261528087331b0bee6ce2cf27c5root 83883827f40a2d97261528087331b0bee6ce2cf27c5root if (sBuf->fence && !wsbmFenceSignaledCached(sBuf->fence, sBuf->fenceType)) { 83983827f40a2d97261528087331b0bee6ce2cf27c5root WSBMLISTADDTAIL(&sBuf->head, &header->delayedBuffers); 84083827f40a2d97261528087331b0bee6ce2cf27c5root header->numDelayed++; 84183827f40a2d97261528087331b0bee6ce2cf27c5root } else { 84283827f40a2d97261528087331b0bee6ce2cf27c5root if (sBuf->fence) 84383827f40a2d97261528087331b0bee6ce2cf27c5root wsbmFenceUnreference(&sBuf->fence); 84483827f40a2d97261528087331b0bee6ce2cf27c5root wsbmSlabFreeBufferLocked(sBuf); 84583827f40a2d97261528087331b0bee6ce2cf27c5root } 84683827f40a2d97261528087331b0bee6ce2cf27c5root 84783827f40a2d97261528087331b0bee6ce2cf27c5root WSBM_MUTEX_UNLOCK(&header->mutex); 84883827f40a2d97261528087331b0bee6ce2cf27c5root} 84983827f40a2d97261528087331b0bee6ce2cf27c5root 85083827f40a2d97261528087331b0bee6ce2cf27c5rootstatic void 85183827f40a2d97261528087331b0bee6ce2cf27c5rootwaitIdleLocked(struct _WsbmSlabBuffer *sBuf, int lazy) 85283827f40a2d97261528087331b0bee6ce2cf27c5root{ 85383827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmBufStorage *storage = &sBuf->storage; 85483827f40a2d97261528087331b0bee6ce2cf27c5root 85583827f40a2d97261528087331b0bee6ce2cf27c5root while (sBuf->unFenced || sBuf->fence != NULL) { 85683827f40a2d97261528087331b0bee6ce2cf27c5root 85783827f40a2d97261528087331b0bee6ce2cf27c5root if (sBuf->unFenced) 85883827f40a2d97261528087331b0bee6ce2cf27c5root WSBM_COND_WAIT(&sBuf->event, &storage->mutex); 85983827f40a2d97261528087331b0bee6ce2cf27c5root 86083827f40a2d97261528087331b0bee6ce2cf27c5root if (sBuf->fence != NULL) { 86183827f40a2d97261528087331b0bee6ce2cf27c5root if (!wsbmFenceSignaled(sBuf->fence, sBuf->fenceType)) { 86283827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmFenceObject *fence = 86383827f40a2d97261528087331b0bee6ce2cf27c5root wsbmFenceReference(sBuf->fence); 86483827f40a2d97261528087331b0bee6ce2cf27c5root 86583827f40a2d97261528087331b0bee6ce2cf27c5root WSBM_MUTEX_UNLOCK(&storage->mutex); 86683827f40a2d97261528087331b0bee6ce2cf27c5root (void)wsbmFenceFinish(fence, sBuf->fenceType, lazy); 86783827f40a2d97261528087331b0bee6ce2cf27c5root WSBM_MUTEX_LOCK(&storage->mutex); 86883827f40a2d97261528087331b0bee6ce2cf27c5root if (sBuf->fence == fence) 86983827f40a2d97261528087331b0bee6ce2cf27c5root wsbmFenceUnreference(&sBuf->fence); 87083827f40a2d97261528087331b0bee6ce2cf27c5root 87183827f40a2d97261528087331b0bee6ce2cf27c5root wsbmFenceUnreference(&fence); 87283827f40a2d97261528087331b0bee6ce2cf27c5root } else { 87383827f40a2d97261528087331b0bee6ce2cf27c5root wsbmFenceUnreference(&sBuf->fence); 87483827f40a2d97261528087331b0bee6ce2cf27c5root } 87583827f40a2d97261528087331b0bee6ce2cf27c5root } 87683827f40a2d97261528087331b0bee6ce2cf27c5root } 87783827f40a2d97261528087331b0bee6ce2cf27c5root} 87883827f40a2d97261528087331b0bee6ce2cf27c5root 87983827f40a2d97261528087331b0bee6ce2cf27c5rootstatic int 88083827f40a2d97261528087331b0bee6ce2cf27c5rootpool_waitIdle(struct _WsbmBufStorage *buf, int lazy) 88183827f40a2d97261528087331b0bee6ce2cf27c5root{ 88283827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmSlabBuffer *sBuf = slabBuffer(buf); 88383827f40a2d97261528087331b0bee6ce2cf27c5root 88483827f40a2d97261528087331b0bee6ce2cf27c5root WSBM_MUTEX_LOCK(&buf->mutex); 88583827f40a2d97261528087331b0bee6ce2cf27c5root waitIdleLocked(sBuf, lazy); 88683827f40a2d97261528087331b0bee6ce2cf27c5root WSBM_MUTEX_UNLOCK(&buf->mutex); 88783827f40a2d97261528087331b0bee6ce2cf27c5root 88883827f40a2d97261528087331b0bee6ce2cf27c5root return 0; 88983827f40a2d97261528087331b0bee6ce2cf27c5root} 89083827f40a2d97261528087331b0bee6ce2cf27c5root 89183827f40a2d97261528087331b0bee6ce2cf27c5rootstatic int 8923795b36d0c937666a5bddc352c781d5e0beec26bThierry Strudelpool_map(struct _WsbmBufStorage *buf, unsigned mode __attribute__ ((unused)), void **virtual) 89383827f40a2d97261528087331b0bee6ce2cf27c5root{ 89483827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmSlabBuffer *sBuf = slabBuffer(buf); 89583827f40a2d97261528087331b0bee6ce2cf27c5root 89683827f40a2d97261528087331b0bee6ce2cf27c5root *virtual = sBuf->virtual; 89783827f40a2d97261528087331b0bee6ce2cf27c5root 89883827f40a2d97261528087331b0bee6ce2cf27c5root return 0; 89983827f40a2d97261528087331b0bee6ce2cf27c5root} 90083827f40a2d97261528087331b0bee6ce2cf27c5root 90183827f40a2d97261528087331b0bee6ce2cf27c5rootstatic void 9023795b36d0c937666a5bddc352c781d5e0beec26bThierry Strudelpool_releaseFromCpu(struct _WsbmBufStorage *buf, unsigned mode __attribute__ ((unused))) 90383827f40a2d97261528087331b0bee6ce2cf27c5root{ 90483827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmSlabBuffer *sBuf = slabBuffer(buf); 90583827f40a2d97261528087331b0bee6ce2cf27c5root 90683827f40a2d97261528087331b0bee6ce2cf27c5root if (wsbmAtomicDecZero(&sBuf->writers)) 90783827f40a2d97261528087331b0bee6ce2cf27c5root WSBM_COND_BROADCAST(&sBuf->event); 90883827f40a2d97261528087331b0bee6ce2cf27c5root} 90983827f40a2d97261528087331b0bee6ce2cf27c5root 91083827f40a2d97261528087331b0bee6ce2cf27c5rootstatic int 91183827f40a2d97261528087331b0bee6ce2cf27c5rootpool_syncForCpu(struct _WsbmBufStorage *buf, unsigned mode) 91283827f40a2d97261528087331b0bee6ce2cf27c5root{ 91383827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmSlabBuffer *sBuf = slabBuffer(buf); 91483827f40a2d97261528087331b0bee6ce2cf27c5root int ret = 0; 91583827f40a2d97261528087331b0bee6ce2cf27c5root 91683827f40a2d97261528087331b0bee6ce2cf27c5root WSBM_MUTEX_LOCK(&buf->mutex); 91783827f40a2d97261528087331b0bee6ce2cf27c5root if ((mode & WSBM_SYNCCPU_DONT_BLOCK)) { 91883827f40a2d97261528087331b0bee6ce2cf27c5root int signaled; 91983827f40a2d97261528087331b0bee6ce2cf27c5root 92083827f40a2d97261528087331b0bee6ce2cf27c5root if (sBuf->unFenced) { 92183827f40a2d97261528087331b0bee6ce2cf27c5root ret = -EBUSY; 92283827f40a2d97261528087331b0bee6ce2cf27c5root goto out_unlock; 92383827f40a2d97261528087331b0bee6ce2cf27c5root } 92483827f40a2d97261528087331b0bee6ce2cf27c5root 92583827f40a2d97261528087331b0bee6ce2cf27c5root if (sBuf->isSlabBuffer) 92683827f40a2d97261528087331b0bee6ce2cf27c5root signaled = (sBuf->fence == NULL) || 92783827f40a2d97261528087331b0bee6ce2cf27c5root wsbmFenceSignaledCached(sBuf->fence, sBuf->fenceType); 92883827f40a2d97261528087331b0bee6ce2cf27c5root else 92983827f40a2d97261528087331b0bee6ce2cf27c5root signaled = (sBuf->fence == NULL) || 93083827f40a2d97261528087331b0bee6ce2cf27c5root wsbmFenceSignaled(sBuf->fence, sBuf->fenceType); 93183827f40a2d97261528087331b0bee6ce2cf27c5root 93283827f40a2d97261528087331b0bee6ce2cf27c5root ret = 0; 93383827f40a2d97261528087331b0bee6ce2cf27c5root if (signaled) { 93483827f40a2d97261528087331b0bee6ce2cf27c5root wsbmFenceUnreference(&sBuf->fence); 93583827f40a2d97261528087331b0bee6ce2cf27c5root wsbmAtomicInc(&sBuf->writers); 93683827f40a2d97261528087331b0bee6ce2cf27c5root } else 93783827f40a2d97261528087331b0bee6ce2cf27c5root ret = -EBUSY; 93883827f40a2d97261528087331b0bee6ce2cf27c5root goto out_unlock; 93983827f40a2d97261528087331b0bee6ce2cf27c5root } 94083827f40a2d97261528087331b0bee6ce2cf27c5root waitIdleLocked(sBuf, 0); 94183827f40a2d97261528087331b0bee6ce2cf27c5root wsbmAtomicInc(&sBuf->writers); 94283827f40a2d97261528087331b0bee6ce2cf27c5root out_unlock: 94383827f40a2d97261528087331b0bee6ce2cf27c5root WSBM_MUTEX_UNLOCK(&buf->mutex); 94483827f40a2d97261528087331b0bee6ce2cf27c5root return ret; 94583827f40a2d97261528087331b0bee6ce2cf27c5root} 94683827f40a2d97261528087331b0bee6ce2cf27c5root 94783827f40a2d97261528087331b0bee6ce2cf27c5rootstatic void 9483795b36d0c937666a5bddc352c781d5e0beec26bThierry Strudelpool_unmap(struct _WsbmBufStorage *buf __attribute__ ((unused))) 94983827f40a2d97261528087331b0bee6ce2cf27c5root{ 95083827f40a2d97261528087331b0bee6ce2cf27c5root ; 95183827f40a2d97261528087331b0bee6ce2cf27c5root} 95283827f40a2d97261528087331b0bee6ce2cf27c5root 95383827f40a2d97261528087331b0bee6ce2cf27c5rootstatic unsigned long 95483827f40a2d97261528087331b0bee6ce2cf27c5rootpool_poolOffset(struct _WsbmBufStorage *buf) 95583827f40a2d97261528087331b0bee6ce2cf27c5root{ 95683827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmSlabBuffer *sBuf = slabBuffer(buf); 95783827f40a2d97261528087331b0bee6ce2cf27c5root 95883827f40a2d97261528087331b0bee6ce2cf27c5root return sBuf->start; 95983827f40a2d97261528087331b0bee6ce2cf27c5root} 96083827f40a2d97261528087331b0bee6ce2cf27c5root 96183827f40a2d97261528087331b0bee6ce2cf27c5rootstatic unsigned long 96283827f40a2d97261528087331b0bee6ce2cf27c5rootpool_size(struct _WsbmBufStorage *buf) 96383827f40a2d97261528087331b0bee6ce2cf27c5root{ 96483827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmSlabBuffer *sBuf = slabBuffer(buf); 96583827f40a2d97261528087331b0bee6ce2cf27c5root 96683827f40a2d97261528087331b0bee6ce2cf27c5root if (!sBuf->isSlabBuffer) 96783827f40a2d97261528087331b0bee6ce2cf27c5root return sBuf->requestedSize; 96883827f40a2d97261528087331b0bee6ce2cf27c5root 96983827f40a2d97261528087331b0bee6ce2cf27c5root return sBuf->parent->header->bufSize; 97083827f40a2d97261528087331b0bee6ce2cf27c5root} 97183827f40a2d97261528087331b0bee6ce2cf27c5root 97283827f40a2d97261528087331b0bee6ce2cf27c5rootstatic struct _WsbmKernelBuf * 97383827f40a2d97261528087331b0bee6ce2cf27c5rootpool_kernel(struct _WsbmBufStorage *buf) 97483827f40a2d97261528087331b0bee6ce2cf27c5root{ 97583827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmSlabBuffer *sBuf = slabBuffer(buf); 97683827f40a2d97261528087331b0bee6ce2cf27c5root 97783827f40a2d97261528087331b0bee6ce2cf27c5root return (sBuf->isSlabBuffer) ? &sBuf->parent->kbo->kBuf : &sBuf->kBuf; 97883827f40a2d97261528087331b0bee6ce2cf27c5root} 97983827f40a2d97261528087331b0bee6ce2cf27c5root 98083827f40a2d97261528087331b0bee6ce2cf27c5rootstatic unsigned long 98183827f40a2d97261528087331b0bee6ce2cf27c5rootpool_offset(struct _WsbmBufStorage *buf) 98283827f40a2d97261528087331b0bee6ce2cf27c5root{ 98383827f40a2d97261528087331b0bee6ce2cf27c5root return pool_kernel(buf)->gpuOffset + pool_poolOffset(buf); 98483827f40a2d97261528087331b0bee6ce2cf27c5root} 98583827f40a2d97261528087331b0bee6ce2cf27c5root 98683827f40a2d97261528087331b0bee6ce2cf27c5rootstatic void 98783827f40a2d97261528087331b0bee6ce2cf27c5rootpool_fence(struct _WsbmBufStorage *buf, struct _WsbmFenceObject *fence) 98883827f40a2d97261528087331b0bee6ce2cf27c5root{ 98983827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmSlabBuffer *sBuf = slabBuffer(buf); 99083827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmKernelBuf *kBuf; 99183827f40a2d97261528087331b0bee6ce2cf27c5root 99283827f40a2d97261528087331b0bee6ce2cf27c5root WSBM_MUTEX_LOCK(&buf->mutex); 99383827f40a2d97261528087331b0bee6ce2cf27c5root if (sBuf->fence) 99483827f40a2d97261528087331b0bee6ce2cf27c5root wsbmFenceUnreference(&sBuf->fence); 99583827f40a2d97261528087331b0bee6ce2cf27c5root 99683827f40a2d97261528087331b0bee6ce2cf27c5root kBuf = pool_kernel(buf); 99783827f40a2d97261528087331b0bee6ce2cf27c5root sBuf->fenceType = kBuf->fence_type_mask; 99883827f40a2d97261528087331b0bee6ce2cf27c5root if (!wsbmFenceSignaledCached(fence, sBuf->fenceType)) 99983827f40a2d97261528087331b0bee6ce2cf27c5root sBuf->fence = wsbmFenceReference(fence); 100083827f40a2d97261528087331b0bee6ce2cf27c5root 100183827f40a2d97261528087331b0bee6ce2cf27c5root sBuf->unFenced = 0; 100283827f40a2d97261528087331b0bee6ce2cf27c5root WSBM_COND_BROADCAST(&sBuf->event); 100383827f40a2d97261528087331b0bee6ce2cf27c5root WSBM_MUTEX_UNLOCK(&buf->mutex); 100483827f40a2d97261528087331b0bee6ce2cf27c5root} 100583827f40a2d97261528087331b0bee6ce2cf27c5root 100683827f40a2d97261528087331b0bee6ce2cf27c5rootstatic int 100783827f40a2d97261528087331b0bee6ce2cf27c5rootpool_validate(struct _WsbmBufStorage *buf, 10083795b36d0c937666a5bddc352c781d5e0beec26bThierry Strudel uint64_t set_flags __attribute__ ((unused)), uint64_t clr_flags __attribute__ ((unused))) 100983827f40a2d97261528087331b0bee6ce2cf27c5root{ 101083827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmSlabBuffer *sBuf = slabBuffer(buf); 101183827f40a2d97261528087331b0bee6ce2cf27c5root 101283827f40a2d97261528087331b0bee6ce2cf27c5root WSBM_MUTEX_LOCK(&buf->mutex); 101383827f40a2d97261528087331b0bee6ce2cf27c5root while (wsbmAtomicRead(&sBuf->writers) != 0) { 101483827f40a2d97261528087331b0bee6ce2cf27c5root WSBM_COND_WAIT(&sBuf->event, &buf->mutex); 101583827f40a2d97261528087331b0bee6ce2cf27c5root } 101683827f40a2d97261528087331b0bee6ce2cf27c5root 101783827f40a2d97261528087331b0bee6ce2cf27c5root sBuf->unFenced = 1; 101883827f40a2d97261528087331b0bee6ce2cf27c5root WSBM_MUTEX_UNLOCK(&buf->mutex); 101983827f40a2d97261528087331b0bee6ce2cf27c5root return 0; 102083827f40a2d97261528087331b0bee6ce2cf27c5root} 102183827f40a2d97261528087331b0bee6ce2cf27c5root 102283827f40a2d97261528087331b0bee6ce2cf27c5rootstatic void 102383827f40a2d97261528087331b0bee6ce2cf27c5rootpool_unvalidate(struct _WsbmBufStorage *buf) 102483827f40a2d97261528087331b0bee6ce2cf27c5root{ 102583827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmSlabBuffer *sBuf = slabBuffer(buf); 102683827f40a2d97261528087331b0bee6ce2cf27c5root 102783827f40a2d97261528087331b0bee6ce2cf27c5root WSBM_MUTEX_LOCK(&buf->mutex); 102883827f40a2d97261528087331b0bee6ce2cf27c5root if (sBuf->unFenced) { 102983827f40a2d97261528087331b0bee6ce2cf27c5root sBuf->unFenced = 0; 103083827f40a2d97261528087331b0bee6ce2cf27c5root WSBM_COND_BROADCAST(&sBuf->event); 103183827f40a2d97261528087331b0bee6ce2cf27c5root } 103283827f40a2d97261528087331b0bee6ce2cf27c5root WSBM_MUTEX_UNLOCK(&buf->mutex); 103383827f40a2d97261528087331b0bee6ce2cf27c5root} 103483827f40a2d97261528087331b0bee6ce2cf27c5root 103583827f40a2d97261528087331b0bee6ce2cf27c5rootstruct _WsbmSlabCache * 103683827f40a2d97261528087331b0bee6ce2cf27c5rootwsbmSlabCacheInit(uint32_t checkIntervalMsec, uint32_t slabTimeoutMsec) 103783827f40a2d97261528087331b0bee6ce2cf27c5root{ 103883827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmSlabCache *tmp; 103983827f40a2d97261528087331b0bee6ce2cf27c5root 104083827f40a2d97261528087331b0bee6ce2cf27c5root tmp = calloc(1, sizeof(*tmp)); 104183827f40a2d97261528087331b0bee6ce2cf27c5root if (!tmp) 104283827f40a2d97261528087331b0bee6ce2cf27c5root return NULL; 104383827f40a2d97261528087331b0bee6ce2cf27c5root 104483827f40a2d97261528087331b0bee6ce2cf27c5root WSBM_MUTEX_INIT(&tmp->mutex); 104583827f40a2d97261528087331b0bee6ce2cf27c5root WSBM_MUTEX_LOCK(&tmp->mutex); 104683827f40a2d97261528087331b0bee6ce2cf27c5root tmp->slabTimeout.tv_usec = slabTimeoutMsec * 1000; 104783827f40a2d97261528087331b0bee6ce2cf27c5root tmp->slabTimeout.tv_sec = tmp->slabTimeout.tv_usec / 1000000; 104883827f40a2d97261528087331b0bee6ce2cf27c5root tmp->slabTimeout.tv_usec -= tmp->slabTimeout.tv_sec * 1000000; 104983827f40a2d97261528087331b0bee6ce2cf27c5root 105083827f40a2d97261528087331b0bee6ce2cf27c5root tmp->checkInterval.tv_usec = checkIntervalMsec * 1000; 105183827f40a2d97261528087331b0bee6ce2cf27c5root tmp->checkInterval.tv_sec = tmp->checkInterval.tv_usec / 1000000; 105283827f40a2d97261528087331b0bee6ce2cf27c5root tmp->checkInterval.tv_usec -= tmp->checkInterval.tv_sec * 1000000; 105383827f40a2d97261528087331b0bee6ce2cf27c5root 105483827f40a2d97261528087331b0bee6ce2cf27c5root gettimeofday(&tmp->nextCheck, NULL); 105583827f40a2d97261528087331b0bee6ce2cf27c5root wsbmTimeAdd(&tmp->nextCheck, &tmp->checkInterval); 105683827f40a2d97261528087331b0bee6ce2cf27c5root WSBMINITLISTHEAD(&tmp->timeoutList); 105783827f40a2d97261528087331b0bee6ce2cf27c5root WSBMINITLISTHEAD(&tmp->unCached); 105883827f40a2d97261528087331b0bee6ce2cf27c5root WSBMINITLISTHEAD(&tmp->cached); 105983827f40a2d97261528087331b0bee6ce2cf27c5root WSBM_MUTEX_UNLOCK(&tmp->mutex); 106083827f40a2d97261528087331b0bee6ce2cf27c5root 106183827f40a2d97261528087331b0bee6ce2cf27c5root return tmp; 106283827f40a2d97261528087331b0bee6ce2cf27c5root} 106383827f40a2d97261528087331b0bee6ce2cf27c5root 106483827f40a2d97261528087331b0bee6ce2cf27c5rootvoid 106583827f40a2d97261528087331b0bee6ce2cf27c5rootwsbmSlabCacheFinish(struct _WsbmSlabCache *cache) 106683827f40a2d97261528087331b0bee6ce2cf27c5root{ 106783827f40a2d97261528087331b0bee6ce2cf27c5root struct timeval time; 106883827f40a2d97261528087331b0bee6ce2cf27c5root 106983827f40a2d97261528087331b0bee6ce2cf27c5root time = cache->nextCheck; 107083827f40a2d97261528087331b0bee6ce2cf27c5root WSBM_MUTEX_LOCK(&cache->mutex); 107183827f40a2d97261528087331b0bee6ce2cf27c5root wsbmTimeAdd(&time, &cache->checkInterval); 107283827f40a2d97261528087331b0bee6ce2cf27c5root wsbmFreeTimeoutKBOsLocked(cache, &time); 107383827f40a2d97261528087331b0bee6ce2cf27c5root WSBM_MUTEX_UNLOCK(&cache->mutex); 107483827f40a2d97261528087331b0bee6ce2cf27c5root 107583827f40a2d97261528087331b0bee6ce2cf27c5root assert(cache->timeoutList.next == &cache->timeoutList); 107683827f40a2d97261528087331b0bee6ce2cf27c5root assert(cache->unCached.next == &cache->unCached); 107783827f40a2d97261528087331b0bee6ce2cf27c5root assert(cache->cached.next == &cache->cached); 107883827f40a2d97261528087331b0bee6ce2cf27c5root 107983827f40a2d97261528087331b0bee6ce2cf27c5root WSBM_MUTEX_FREE(&cache->mutex); 108083827f40a2d97261528087331b0bee6ce2cf27c5root free(cache); 108183827f40a2d97261528087331b0bee6ce2cf27c5root} 108283827f40a2d97261528087331b0bee6ce2cf27c5root 108383827f40a2d97261528087331b0bee6ce2cf27c5rootstatic void 108483827f40a2d97261528087331b0bee6ce2cf27c5rootwsbmInitSizeHeader(struct _WsbmSlabPool *slabPool, uint32_t size, 108583827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmSlabSizeHeader *header) 108683827f40a2d97261528087331b0bee6ce2cf27c5root{ 108783827f40a2d97261528087331b0bee6ce2cf27c5root WSBM_MUTEX_INIT(&header->mutex); 108883827f40a2d97261528087331b0bee6ce2cf27c5root WSBM_MUTEX_LOCK(&header->mutex); 108983827f40a2d97261528087331b0bee6ce2cf27c5root 109083827f40a2d97261528087331b0bee6ce2cf27c5root WSBMINITLISTHEAD(&header->slabs); 109183827f40a2d97261528087331b0bee6ce2cf27c5root WSBMINITLISTHEAD(&header->freeSlabs); 109283827f40a2d97261528087331b0bee6ce2cf27c5root WSBMINITLISTHEAD(&header->delayedBuffers); 109383827f40a2d97261528087331b0bee6ce2cf27c5root 109483827f40a2d97261528087331b0bee6ce2cf27c5root header->numDelayed = 0; 109583827f40a2d97261528087331b0bee6ce2cf27c5root header->slabPool = slabPool; 109683827f40a2d97261528087331b0bee6ce2cf27c5root header->bufSize = size; 109783827f40a2d97261528087331b0bee6ce2cf27c5root 109883827f40a2d97261528087331b0bee6ce2cf27c5root WSBM_MUTEX_UNLOCK(&header->mutex); 109983827f40a2d97261528087331b0bee6ce2cf27c5root} 110083827f40a2d97261528087331b0bee6ce2cf27c5root 110183827f40a2d97261528087331b0bee6ce2cf27c5rootstatic void 110283827f40a2d97261528087331b0bee6ce2cf27c5rootwsbmFinishSizeHeader(struct _WsbmSlabSizeHeader *header) 110383827f40a2d97261528087331b0bee6ce2cf27c5root{ 110483827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmListHead *list, *next; 110583827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmSlabBuffer *sBuf; 110683827f40a2d97261528087331b0bee6ce2cf27c5root 110783827f40a2d97261528087331b0bee6ce2cf27c5root WSBM_MUTEX_LOCK(&header->mutex); 110883827f40a2d97261528087331b0bee6ce2cf27c5root WSBMLISTFOREACHSAFE(list, next, &header->delayedBuffers) { 110983827f40a2d97261528087331b0bee6ce2cf27c5root sBuf = WSBMLISTENTRY(list, struct _WsbmSlabBuffer, head); 111083827f40a2d97261528087331b0bee6ce2cf27c5root 111183827f40a2d97261528087331b0bee6ce2cf27c5root if (sBuf->fence) { 111283827f40a2d97261528087331b0bee6ce2cf27c5root (void)wsbmFenceFinish(sBuf->fence, sBuf->fenceType, 0); 111383827f40a2d97261528087331b0bee6ce2cf27c5root wsbmFenceUnreference(&sBuf->fence); 111483827f40a2d97261528087331b0bee6ce2cf27c5root } 111583827f40a2d97261528087331b0bee6ce2cf27c5root header->numDelayed--; 111683827f40a2d97261528087331b0bee6ce2cf27c5root wsbmSlabFreeBufferLocked(sBuf); 111783827f40a2d97261528087331b0bee6ce2cf27c5root } 111883827f40a2d97261528087331b0bee6ce2cf27c5root WSBM_MUTEX_UNLOCK(&header->mutex); 111983827f40a2d97261528087331b0bee6ce2cf27c5root WSBM_MUTEX_FREE(&header->mutex); 112083827f40a2d97261528087331b0bee6ce2cf27c5root} 112183827f40a2d97261528087331b0bee6ce2cf27c5root 112283827f40a2d97261528087331b0bee6ce2cf27c5rootstatic void 112383827f40a2d97261528087331b0bee6ce2cf27c5rootpool_takedown(struct _WsbmBufferPool *pool) 112483827f40a2d97261528087331b0bee6ce2cf27c5root{ 112583827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmSlabPool *slabPool = slabPoolFromPool(pool); 11263795b36d0c937666a5bddc352c781d5e0beec26bThierry Strudel unsigned int i; 112783827f40a2d97261528087331b0bee6ce2cf27c5root 112883827f40a2d97261528087331b0bee6ce2cf27c5root for (i = 0; i < slabPool->numBuckets; ++i) { 112983827f40a2d97261528087331b0bee6ce2cf27c5root wsbmFinishSizeHeader(&slabPool->headers[i]); 113083827f40a2d97261528087331b0bee6ce2cf27c5root } 113183827f40a2d97261528087331b0bee6ce2cf27c5root 113283827f40a2d97261528087331b0bee6ce2cf27c5root free(slabPool->headers); 113383827f40a2d97261528087331b0bee6ce2cf27c5root free(slabPool->bucketSizes); 113483827f40a2d97261528087331b0bee6ce2cf27c5root free(slabPool); 113583827f40a2d97261528087331b0bee6ce2cf27c5root} 113683827f40a2d97261528087331b0bee6ce2cf27c5root 113783827f40a2d97261528087331b0bee6ce2cf27c5rootstruct _WsbmBufferPool * 113883827f40a2d97261528087331b0bee6ce2cf27c5rootwsbmSlabPoolInit(int fd, 113983827f40a2d97261528087331b0bee6ce2cf27c5root uint32_t devOffset, 114083827f40a2d97261528087331b0bee6ce2cf27c5root uint32_t placement, 114183827f40a2d97261528087331b0bee6ce2cf27c5root uint32_t validMask, 114283827f40a2d97261528087331b0bee6ce2cf27c5root uint32_t smallestSize, 114383827f40a2d97261528087331b0bee6ce2cf27c5root uint32_t numSizes, 114483827f40a2d97261528087331b0bee6ce2cf27c5root uint32_t desiredNumBuffers, 114583827f40a2d97261528087331b0bee6ce2cf27c5root uint32_t maxSlabSize, 114683827f40a2d97261528087331b0bee6ce2cf27c5root uint32_t pageAlignment, struct _WsbmSlabCache *cache) 114783827f40a2d97261528087331b0bee6ce2cf27c5root{ 114883827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmBufferPool *pool; 114983827f40a2d97261528087331b0bee6ce2cf27c5root struct _WsbmSlabPool *slabPool; 115083827f40a2d97261528087331b0bee6ce2cf27c5root uint32_t i; 115183827f40a2d97261528087331b0bee6ce2cf27c5root 115283827f40a2d97261528087331b0bee6ce2cf27c5root slabPool = calloc(1, sizeof(*slabPool)); 115383827f40a2d97261528087331b0bee6ce2cf27c5root if (!slabPool) 115483827f40a2d97261528087331b0bee6ce2cf27c5root return NULL; 115583827f40a2d97261528087331b0bee6ce2cf27c5root 115683827f40a2d97261528087331b0bee6ce2cf27c5root pool = &slabPool->pool; 115783827f40a2d97261528087331b0bee6ce2cf27c5root 115883827f40a2d97261528087331b0bee6ce2cf27c5root slabPool->bucketSizes = calloc(numSizes, sizeof(*slabPool->bucketSizes)); 115983827f40a2d97261528087331b0bee6ce2cf27c5root if (!slabPool->bucketSizes) 116083827f40a2d97261528087331b0bee6ce2cf27c5root goto out_err0; 116183827f40a2d97261528087331b0bee6ce2cf27c5root 116283827f40a2d97261528087331b0bee6ce2cf27c5root slabPool->headers = calloc(numSizes, sizeof(*slabPool->headers)); 116383827f40a2d97261528087331b0bee6ce2cf27c5root if (!slabPool->headers) 116483827f40a2d97261528087331b0bee6ce2cf27c5root goto out_err1; 116583827f40a2d97261528087331b0bee6ce2cf27c5root 116683827f40a2d97261528087331b0bee6ce2cf27c5root slabPool->devOffset = devOffset; 116783827f40a2d97261528087331b0bee6ce2cf27c5root slabPool->cache = cache; 116883827f40a2d97261528087331b0bee6ce2cf27c5root slabPool->proposedPlacement = placement; 116983827f40a2d97261528087331b0bee6ce2cf27c5root slabPool->validMask = validMask; 117083827f40a2d97261528087331b0bee6ce2cf27c5root slabPool->numBuckets = numSizes; 117183827f40a2d97261528087331b0bee6ce2cf27c5root slabPool->pageSize = getpagesize(); 117283827f40a2d97261528087331b0bee6ce2cf27c5root slabPool->pageAlignment = pageAlignment; 117383827f40a2d97261528087331b0bee6ce2cf27c5root slabPool->maxSlabSize = maxSlabSize; 117483827f40a2d97261528087331b0bee6ce2cf27c5root slabPool->desiredNumBuffers = desiredNumBuffers; 117583827f40a2d97261528087331b0bee6ce2cf27c5root 117683827f40a2d97261528087331b0bee6ce2cf27c5root for (i = 0; i < slabPool->numBuckets; ++i) { 117783827f40a2d97261528087331b0bee6ce2cf27c5root slabPool->bucketSizes[i] = (smallestSize << i); 117883827f40a2d97261528087331b0bee6ce2cf27c5root wsbmInitSizeHeader(slabPool, slabPool->bucketSizes[i], 117983827f40a2d97261528087331b0bee6ce2cf27c5root &slabPool->headers[i]); 118083827f40a2d97261528087331b0bee6ce2cf27c5root } 118183827f40a2d97261528087331b0bee6ce2cf27c5root 118283827f40a2d97261528087331b0bee6ce2cf27c5root pool->fd = fd; 118383827f40a2d97261528087331b0bee6ce2cf27c5root pool->map = &pool_map; 118483827f40a2d97261528087331b0bee6ce2cf27c5root pool->unmap = &pool_unmap; 118583827f40a2d97261528087331b0bee6ce2cf27c5root pool->destroy = &pool_destroy; 118683827f40a2d97261528087331b0bee6ce2cf27c5root pool->offset = &pool_offset; 118783827f40a2d97261528087331b0bee6ce2cf27c5root pool->poolOffset = &pool_poolOffset; 118883827f40a2d97261528087331b0bee6ce2cf27c5root pool->size = &pool_size; 118983827f40a2d97261528087331b0bee6ce2cf27c5root pool->create = &pool_create; 119083827f40a2d97261528087331b0bee6ce2cf27c5root pool->fence = &pool_fence; 119183827f40a2d97261528087331b0bee6ce2cf27c5root pool->kernel = &pool_kernel; 119283827f40a2d97261528087331b0bee6ce2cf27c5root pool->validate = &pool_validate; 119383827f40a2d97261528087331b0bee6ce2cf27c5root pool->unvalidate = &pool_unvalidate; 119483827f40a2d97261528087331b0bee6ce2cf27c5root pool->waitIdle = &pool_waitIdle; 119583827f40a2d97261528087331b0bee6ce2cf27c5root pool->takeDown = &pool_takedown; 119683827f40a2d97261528087331b0bee6ce2cf27c5root pool->releasefromcpu = &pool_releaseFromCpu; 119783827f40a2d97261528087331b0bee6ce2cf27c5root pool->syncforcpu = &pool_syncForCpu; 119883827f40a2d97261528087331b0bee6ce2cf27c5root 119983827f40a2d97261528087331b0bee6ce2cf27c5root return pool; 120083827f40a2d97261528087331b0bee6ce2cf27c5root 120183827f40a2d97261528087331b0bee6ce2cf27c5root out_err1: 120283827f40a2d97261528087331b0bee6ce2cf27c5root free(slabPool->bucketSizes); 120383827f40a2d97261528087331b0bee6ce2cf27c5root out_err0: 120483827f40a2d97261528087331b0bee6ce2cf27c5root free(slabPool); 120583827f40a2d97261528087331b0bee6ce2cf27c5root 120683827f40a2d97261528087331b0bee6ce2cf27c5root return NULL; 120783827f40a2d97261528087331b0bee6ce2cf27c5root} 1208