From patchwork Mon Sep 14 16:27:27 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chris Wilson X-Patchwork-Id: 47337 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id n8EGRfAe015513 for ; Mon, 14 Sep 2009 16:27:41 GMT Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 097D29F02B; Mon, 14 Sep 2009 09:27:41 -0700 (PDT) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from relay.fireflyinternet.com (unknown [66.98.244.53]) by gabe.freedesktop.org (Postfix) with ESMTP id 140F89E916 for ; Mon, 14 Sep 2009 09:27:38 -0700 (PDT) Received: from fireflyinternet.com (unverified [94.30.43.99]) by relay.fireflyinternet.com (FireflyRelay1) with ESMTP id 49747222 for ; Mon, 14 Sep 2009 17:27:39 +0100 Received: from localhost.localdomain (unverified [78.156.66.37]) by fireflyinternet.com (Firefly Internet SMTP) with ESMTP id 51427511-1948518 for multiple; Mon, 14 Sep 2009 17:27:33 +0100 From: Chris Wilson To: intel-gfx@lists.freedesktop.org Date: Mon, 14 Sep 2009 17:27:27 +0100 Message-Id: <1252945647-9408-1-git-send-email-chris@chris-wilson.co.uk> X-Mailer: git-send-email 1.6.3.3 X-Originating-IP: 78.156.66.37 Subject: [Intel-gfx] [PATCH] intel: Mark cached bo as purgeable X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.9 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: intel-gfx-bounces@lists.freedesktop.org Errors-To: intel-gfx-bounces@lists.freedesktop.org Set the DONTNEED flag on cached buffers so that the kernel is free to discard those when under memory pressure. Signed-off-by: Chris Wilson --- libdrm/intel/intel_bufmgr_gem.c | 51 +++++++++++++++++++++++++++++++++++++++ shared-core/i915_drm.h | 16 ++++++++++++ 2 files changed, 67 insertions(+), 0 deletions(-) diff --git a/libdrm/intel/intel_bufmgr_gem.c b/libdrm/intel/intel_bufmgr_gem.c index baa0ee6..0c479f7 100644 --- a/libdrm/intel/intel_bufmgr_gem.c +++ b/libdrm/intel/intel_bufmgr_gem.c @@ -206,6 +206,9 @@ drm_intel_gem_bo_set_tiling(drm_intel_bo *bo, uint32_t *tiling_mode, static void drm_intel_gem_bo_unreference(drm_intel_bo *bo); +static void +drm_intel_gem_bo_free(drm_intel_bo *bo); + static struct drm_intel_gem_bo_bucket * drm_intel_gem_bo_bucket_for_size(drm_intel_bufmgr_gem *bufmgr_gem, unsigned long size) @@ -330,6 +333,50 @@ drm_intel_gem_bo_busy(drm_intel_bo *bo) return (ret == 0 && busy.busy); } +static int +drm_intel_gem_bo_madvise(drm_intel_bufmgr_gem *bufmgr_gem, + drm_intel_bo_gem *bo_gem, + int state) +{ + struct drm_i915_gem_madvise madv; + + madv.handle = bo_gem->gem_handle; + madv.madv = state; + madv.retained = 1; + ioctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_MADVISE, &madv); + + return madv.retained; +} + +/* drop the oldest entries that have been purged by the kernel */ +static void +drm_intel_gem_bo_cache_purge(drm_intel_bufmgr *bufmgr) +{ + drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *)bufmgr; + int i; + + pthread_mutex_lock(&bufmgr_gem->lock); + + for (i = 0; i < DRM_INTEL_GEM_BO_BUCKETS; i++) { + struct drm_intel_gem_bo_bucket *bucket = &bufmgr_gem->cache_bucket[i]; + drm_intel_bo_gem *bo_gem; + + while (!DRMLISTEMPTY(&bucket->head)) { + bo_gem = DRMLISTENTRY(drm_intel_bo_gem, bucket->head.next, head); + + if (drm_intel_gem_bo_madvise (bufmgr, bo_gem, I915_MADV_DONTNEED)) + break; + + DRMLISTDEL(&bo_gem->head); + bucket->num_entries--; + + drm_intel_gem_bo_free(&bo_gem->bo); + } + } + + pthread_mutex_unlock(&bufmgr_gem->lock); +} + static drm_intel_bo * drm_intel_gem_bo_alloc_internal(drm_intel_bufmgr *bufmgr, const char *name, unsigned long size, unsigned int alignment, @@ -406,6 +453,9 @@ drm_intel_gem_bo_alloc_internal(drm_intel_bufmgr *bufmgr, const char *name, return NULL; } bo_gem->bo.bufmgr = bufmgr; + } else { + if(!drm_intel_gem_bo_madvise(bufmgr_gem, bo_gem, I915_MADV_WILLNEED)) + drm_intel_gem_bo_cache_purge(bufmgr); } bo_gem->name = name; @@ -615,6 +665,7 @@ drm_intel_gem_bo_unreference_locked(drm_intel_bo *bo) DRMLISTADDTAIL(&bo_gem->head, &bucket->head); bucket->num_entries++; + drm_intel_gem_bo_madvise(bufmgr_gem, bo_gem, I915_MADV_DONTNEED); drm_intel_gem_cleanup_bo_cache(bufmgr_gem, time.tv_sec); } else { drm_intel_gem_bo_free(bo); diff --git a/shared-core/i915_drm.h b/shared-core/i915_drm.h index 2539966..b214600 100644 --- a/shared-core/i915_drm.h +++ b/shared-core/i915_drm.h @@ -206,6 +206,7 @@ typedef struct drm_i915_sarea { #define DRM_I915_GEM_GET_APERTURE 0x23 #define DRM_I915_GEM_MMAP_GTT 0x24 #define DRM_I915_GET_PIPE_FROM_CRTC_ID 0x25 +#define DRM_I915_GEM_MADVISE 0x26 #define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t) #define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH) @@ -244,6 +245,7 @@ typedef struct drm_i915_sarea { #define DRM_IOCTL_I915_GEM_GET_TILING DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_GET_TILING, struct drm_i915_gem_get_tiling) #define DRM_IOCTL_I915_GEM_GET_APERTURE DRM_IOR (DRM_COMMAND_BASE + DRM_I915_GEM_GET_APERTURE, struct drm_i915_gem_get_aperture) #define DRM_IOCTL_I915_GET_PIPE_FROM_CRTC_ID DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GET_PIPE_FROM_CRTC_ID, struct drm_i915_get_pipe_from_crtc_id) +#define DRM_IOCTL_I915_GEM_MADVISE DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MADVISE, struct drm_i915_gem_madvise) /* Asynchronous page flipping: */ @@ -727,4 +729,18 @@ struct drm_i915_get_pipe_from_crtc_id { uint32_t pipe; }; +#define I915_MADV_WILLNEED 0 +#define I915_MADV_DONTNEED 1 + +struct drm_i915_gem_madvise { + /** Handle of the buffer to change the backing store advice. */ + uint32_t handle; + + /** Advice. */ + uint32_t madv; + + /** Whether or not the backing store still exists */ + uint32_t retained; +}; + #endif /* _I915_DRM_H_ */