i965: Remove clearing of bo->map_gtt after failure
[mesa.git] / src / mesa / drivers / dri / i965 / brw_bufmgr.c
index 9475d2b30acaf4d1fea047753d96f9f0b001b70f..f49b8866222aac42ad97010d5689a0f119950b7b 100644 (file)
@@ -324,6 +324,7 @@ retry:
          goto err;
 
       bo->size = bo_size;
+      bo->idle = true;
 
       memclear(create);
       create.size = bo_size;
@@ -375,8 +376,16 @@ brw_bo_alloc(struct brw_bufmgr *bufmgr,
 
 struct brw_bo *
 brw_bo_alloc_tiled(struct brw_bufmgr *bufmgr, const char *name,
-                   int x, int y, int cpp, uint32_t tiling,
-                   uint32_t *pitch, unsigned flags)
+                   uint64_t size, uint32_t tiling_mode, uint32_t pitch,
+                   unsigned flags)
+{
+   return bo_alloc_internal(bufmgr, name, size, flags, tiling_mode, pitch, 0);
+}
+
+struct brw_bo *
+brw_bo_alloc_tiled_2d(struct brw_bufmgr *bufmgr, const char *name,
+                      int x, int y, int cpp, uint32_t tiling,
+                      uint32_t *pitch, unsigned flags)
 {
    uint64_t size;
    uint32_t stride;
@@ -537,21 +546,6 @@ bo_free(struct brw_bo *bo)
    free(bo);
 }
 
-static void
-bo_mark_mmaps_incoherent(struct brw_bo *bo)
-{
-#if HAVE_VALGRIND
-   if (bo->map_cpu)
-      VALGRIND_MAKE_MEM_NOACCESS(bo->map_cpu, bo->size);
-
-   if (bo->map_wc)
-      VALGRIND_MAKE_MEM_NOACCESS(bo->map_wc, bo->size);
-
-   if (bo->map_gtt)
-      VALGRIND_MAKE_MEM_NOACCESS(bo->map_gtt, bo->size);
-#endif
-}
-
 /** Frees all cached buffers significantly older than @time. */
 static void
 cleanup_bo_cache(struct brw_bufmgr *bufmgr, time_t time)
@@ -585,13 +579,6 @@ bo_unreference_final(struct brw_bo *bo, time_t time)
 
    DBG("bo_unreference final: %d (%s)\n", bo->gem_handle, bo->name);
 
-   /* Clear any left-over mappings */
-   if (bo->map_count) {
-      DBG("bo freed with non-zero map-count %d\n", bo->map_count);
-      bo->map_count = 0;
-      bo_mark_mmaps_incoherent(bo);
-   }
-
    bucket = bucket_for_size(bufmgr, bo->size);
    /* Put the buffer into our internal cache for reuse if we can. */
    if (bufmgr->bo_reuse && bo->reusable && bucket != NULL &&
@@ -663,13 +650,11 @@ brw_bo_map_cpu(struct brw_context *brw, struct brw_bo *bo, unsigned flags)
 {
    struct brw_bufmgr *bufmgr = bo->bufmgr;
 
-   pthread_mutex_lock(&bufmgr->lock);
-
    if (!bo->map_cpu) {
       struct drm_i915_gem_mmap mmap_arg;
+      void *map;
 
-      DBG("brw_bo_map_cpu: %d (%s), map_count=%d\n",
-          bo->gem_handle, bo->name, bo->map_count);
+      DBG("brw_bo_map_cpu: %d (%s)\n", bo->gem_handle, bo->name);
 
       memclear(mmap_arg);
       mmap_arg.handle = bo->gem_handle;
@@ -679,25 +664,24 @@ brw_bo_map_cpu(struct brw_context *brw, struct brw_bo *bo, unsigned flags)
          ret = -errno;
          DBG("%s:%d: Error mapping buffer %d (%s): %s .\n",
              __FILE__, __LINE__, bo->gem_handle, bo->name, strerror(errno));
-         pthread_mutex_unlock(&bufmgr->lock);
          return NULL;
       }
-      bo->map_count++;
       VG(VALGRIND_MALLOCLIKE_BLOCK(mmap_arg.addr_ptr, mmap_arg.size, 0, 1));
-      bo->map_cpu = (void *) (uintptr_t) mmap_arg.addr_ptr;
+      map = (void *) (uintptr_t) mmap_arg.addr_ptr;
+
+      if (p_atomic_cmpxchg(&bo->map_cpu, NULL, map)) {
+         VG(VALGRIND_FREELIKE_BLOCK(map, 0));
+         drm_munmap(map, bo->size);
+      }
    }
    DBG("brw_bo_map_cpu: %d (%s) -> %p\n", bo->gem_handle, bo->name,
        bo->map_cpu);
 
-   if (!(flags & MAP_ASYNC)) {
+   if (!(flags & MAP_ASYNC) || !bufmgr->has_llc) {
       set_domain(brw, "CPU mapping", bo, I915_GEM_DOMAIN_CPU,
                  flags & MAP_WRITE ? I915_GEM_DOMAIN_CPU : 0);
    }
 
-   bo_mark_mmaps_incoherent(bo);
-   VG(VALGRIND_MAKE_MEM_DEFINED(bo->map_cpu, bo->size));
-   pthread_mutex_unlock(&bufmgr->lock);
-
    return bo->map_cpu;
 }
 
@@ -706,14 +690,12 @@ brw_bo_map_gtt(struct brw_context *brw, struct brw_bo *bo, unsigned flags)
 {
    struct brw_bufmgr *bufmgr = bo->bufmgr;
 
-   pthread_mutex_lock(&bufmgr->lock);
-
    /* Get a mapping of the buffer if we haven't before. */
    if (bo->map_gtt == NULL) {
       struct drm_i915_gem_mmap_gtt mmap_arg;
+      void *map;
 
-      DBG("bo_map_gtt: mmap %d (%s), map_count=%d\n",
-          bo->gem_handle, bo->name, bo->map_count);
+      DBG("bo_map_gtt: mmap %d (%s)\n", bo->gem_handle, bo->name);
 
       memclear(mmap_arg);
       mmap_arg.handle = bo->gem_handle;
@@ -727,31 +709,30 @@ brw_bo_map_gtt(struct brw_context *brw, struct brw_bo *bo, unsigned flags)
          return NULL;
       }
 
-      /* and mmap it */
-      bo->map_gtt = drm_mmap(0, bo->size, PROT_READ | PROT_WRITE,
-                             MAP_SHARED, bufmgr->fd, mmap_arg.offset);
-      if (bo->map_gtt == MAP_FAILED) {
-         bo->map_gtt = NULL;
+      /* and mmap it.  We don't need to use VALGRIND_MALLOCLIKE_BLOCK
+       * because Valgrind will already intercept this mmap call.
+       */
+      map = drm_mmap(0, bo->size, PROT_READ | PROT_WRITE,
+                     MAP_SHARED, bufmgr->fd, mmap_arg.offset);
+      if (map == MAP_FAILED) {
          DBG("%s:%d: Error mapping buffer %d (%s): %s .\n",
              __FILE__, __LINE__, bo->gem_handle, bo->name, strerror(errno));
-         pthread_mutex_unlock(&bufmgr->lock);
          return NULL;
       }
-      bo->map_count++;
+
+      if (p_atomic_cmpxchg(&bo->map_gtt, NULL, map)) {
+         drm_munmap(map, bo->size);
+      }
    }
 
    DBG("bo_map_gtt: %d (%s) -> %p\n", bo->gem_handle, bo->name,
        bo->map_gtt);
 
-   if (!(flags & MAP_ASYNC)) {
+   if (!(flags & MAP_ASYNC) || !bufmgr->has_llc) {
       set_domain(brw, "GTT mapping", bo,
                  I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
    }
 
-   bo_mark_mmaps_incoherent(bo);
-   VG(VALGRIND_MAKE_MEM_DEFINED(bo->map_gtt, bo->size));
-   pthread_mutex_unlock(&bufmgr->lock);
-
    return bo->map_gtt;
 }
 
@@ -781,31 +762,6 @@ brw_bo_map(struct brw_context *brw, struct brw_bo *bo, unsigned flags)
       return brw_bo_map_gtt(brw, bo, flags);
 }
 
-int
-brw_bo_unmap(struct brw_bo *bo)
-{
-   struct brw_bufmgr *bufmgr = bo->bufmgr;
-   int ret = 0;
-
-   pthread_mutex_lock(&bufmgr->lock);
-
-   if (bo->map_count <= 0) {
-      DBG("attempted to unmap an unmapped bo\n");
-      pthread_mutex_unlock(&bufmgr->lock);
-      /* Preserve the old behaviour of just treating this as a
-       * no-op rather than reporting the error.
-       */
-      return 0;
-   }
-
-   if (--bo->map_count == 0) {
-      bo_mark_mmaps_incoherent(bo);
-   }
-   pthread_mutex_unlock(&bufmgr->lock);
-
-   return ret;
-}
-
 int
 brw_bo_subdata(struct brw_bo *bo, uint64_t offset,
                uint64_t size, const void *data)
@@ -971,8 +927,7 @@ brw_bo_get_tiling(struct brw_bo *bo, uint32_t *tiling_mode,
 }
 
 struct brw_bo *
-brw_bo_gem_create_from_prime(struct brw_bufmgr *bufmgr, int prime_fd,
-                             int size)
+brw_bo_gem_create_from_prime(struct brw_bufmgr *bufmgr, int prime_fd)
 {
    int ret;
    uint32_t handle;
@@ -1013,8 +968,6 @@ brw_bo_gem_create_from_prime(struct brw_bufmgr *bufmgr, int prime_fd,
    ret = lseek(prime_fd, 0, SEEK_END);
    if (ret != -1)
       bo->size = ret;
-   else
-      bo->size = size;
 
    bo->bufmgr = bufmgr;