drm/vmwgfx: Remove the resource avail field
authorThomas Hellstrom <thellstrom@vmware.com>
Wed, 26 Sep 2018 13:41:52 +0000 (15:41 +0200)
committerThomas Hellstrom <thellstrom@vmware.com>
Thu, 27 Sep 2018 13:21:37 +0000 (15:21 +0200)
This field was previously used to prevent a lookup of a resource before its
constructor had run to its end. This was mainly intended for an interface
that is now removed that allowed looking up a resource by its device id.

Currently all affected resources are added to the lookup mechanism (its
TTM prime object is initialized) late in the constructor where it's OK to
look up the resource.

This means we can change the device resource_lock to an ordinary spinlock
instead of an rwlock and remove a locking sequence during lookup.

Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
Reviewed-by: Sinclair Yeh <syeh@vmware.com>
Reviewed-by: Deepak Rawat <drawat@vmware.com>
drivers/gpu/drm/vmwgfx/vmwgfx_context.c
drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c
drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
drivers/gpu/drm/vmwgfx/vmwgfx_resource_priv.h
drivers/gpu/drm/vmwgfx/vmwgfx_shader.c
drivers/gpu/drm/vmwgfx/vmwgfx_simple_resource.c
drivers/gpu/drm/vmwgfx/vmwgfx_so.c
drivers/gpu/drm/vmwgfx/vmwgfx_surface.c

index 7c3cb8efd11a894ecdf5c3993761be809bf68e46..4d502567d24c8b6c97e63703ac14f315d79085da 100644 (file)
@@ -217,9 +217,7 @@ static int vmw_gb_context_init(struct vmw_private *dev_priv,
                }
        }
 
-
-
-       vmw_resource_activate(res, vmw_hw_context_destroy);
+       res->hw_destroy = vmw_hw_context_destroy;
        return 0;
 
 out_cotables:
@@ -274,7 +272,7 @@ static int vmw_context_init(struct vmw_private *dev_priv,
 
        vmw_fifo_commit(dev_priv, sizeof(*cmd));
        vmw_fifo_resource_inc(dev_priv);
-       vmw_resource_activate(res, vmw_hw_context_destroy);
+       res->hw_destroy = vmw_hw_context_destroy;
        return 0;
 
 out_early:
index 1d45714e1d5a061d1da0d1c9b5bbf7a932a3926d..44f3f6f107d3c632caeac9e94a7b2f0035b22a97 100644 (file)
@@ -615,7 +615,7 @@ struct vmw_resource *vmw_cotable_alloc(struct vmw_private *dev_priv,
        vcotbl->type = type;
        vcotbl->ctx = ctx;
 
-       vmw_resource_activate(&vcotbl->res, vmw_hw_cotable_destroy);
+       vcotbl->res.hw_destroy = vmw_hw_cotable_destroy;
 
        return &vcotbl->res;
 
index d9c178e235b4a1dd76e06c704ce6db067323629c..61a84b958d671671cb56c37b6e44a589989d026b 100644 (file)
@@ -667,8 +667,8 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
        mutex_init(&dev_priv->binding_mutex);
        mutex_init(&dev_priv->requested_layout_mutex);
        mutex_init(&dev_priv->global_kms_state_mutex);
-       rwlock_init(&dev_priv->resource_lock);
        ttm_lock_init(&dev_priv->reservation_sem);
+       spin_lock_init(&dev_priv->resource_lock);
        spin_lock_init(&dev_priv->hw_lock);
        spin_lock_init(&dev_priv->waiter_lock);
        spin_lock_init(&dev_priv->cap_lock);
index 61866294147ea6dcbf4fc10e2d78bfe0dacb9987..d83bb70627ecbdcdfd948367edea60b0276ddf32 100644 (file)
@@ -113,21 +113,49 @@ struct vmw_validate_buffer {
 };
 
 struct vmw_res_func;
+
+
+/**
+ * struct vmw-resource - base class for hardware resources
+ *
+ * @kref: For refcounting.
+ * @dev_priv: Pointer to the device private for this resource. Immutable.
+ * @id: Device id. Protected by @dev_priv::resource_lock.
+ * @backup_size: Backup buffer size. Immutable.
+ * @res_dirty: Resource contains data not yet in the backup buffer. Protected
+ * by resource reserved.
+ * @backup_dirty: Backup buffer contains data not yet in the HW resource.
+ * Protecte by resource reserved.
+ * @backup: The backup buffer if any. Protected by resource reserved.
+ * @backup_offset: Offset into the backup buffer if any. Protected by resource
+ * reserved. Note that only a few resource types can have a @backup_offset
+ * different from zero.
+ * @pin_count: The pin count for this resource. A pinned resource has a
+ * pin-count greater than zero. It is not on the resource LRU lists and its
+ * backup buffer is pinned. Hence it can't be evicted.
+ * @func: Method vtable for this resource. Immutable.
+ * @lru_head: List head for the LRU list. Protected by @dev_priv::resource_lock.
+ * @mob_head: List head for the MOB backup list. Protected by @backup reserved.
+ * @binding_head: List head for the context binding list. Protected by
+ * the @dev_priv::binding_mutex
+ * @res_free: The resource destructor.
+ * @hw_destroy: Callback to destroy the resource on the device, as part of
+ * resource destruction.
+ */
 struct vmw_resource {
        struct kref kref;
        struct vmw_private *dev_priv;
        int id;
-       bool avail;
        unsigned long backup_size;
-       bool res_dirty; /* Protected by backup buffer reserved */
-       bool backup_dirty; /* Protected by backup buffer reserved */
+       bool res_dirty;
+       bool backup_dirty;
        struct vmw_buffer_object *backup;
        unsigned long backup_offset;
-       unsigned long pin_count; /* Protected by resource reserved */
+       unsigned long pin_count;
        const struct vmw_res_func *func;
-       struct list_head lru_head; /* Protected by the resource lock */
-       struct list_head mob_head; /* Protected by @backup reserved */
-       struct list_head binding_head; /* Protected by binding_mutex */
+       struct list_head lru_head;
+       struct list_head mob_head;
+       struct list_head binding_head;
        void (*res_free) (struct vmw_resource *res);
        void (*hw_destroy) (struct vmw_resource *res);
 };
@@ -471,7 +499,7 @@ struct vmw_private {
         * Context and surface management.
         */
 
-       rwlock_t resource_lock;
+       spinlock_t resource_lock;
        struct idr res_idr[vmw_res_max];
        /*
         * Block lastclose from racing with firstopen.
index 315b3d60567d4676c0856f1b0e43a63a8974e559..55df79eccd57fe5ac99a99f12073e7e006cbf249 100644 (file)
@@ -58,11 +58,11 @@ void vmw_resource_release_id(struct vmw_resource *res)
        struct vmw_private *dev_priv = res->dev_priv;
        struct idr *idr = &dev_priv->res_idr[res->func->res_type];
 
-       write_lock(&dev_priv->resource_lock);
+       spin_lock(&dev_priv->resource_lock);
        if (res->id != -1)
                idr_remove(idr, res->id);
        res->id = -1;
-       write_unlock(&dev_priv->resource_lock);
+       spin_unlock(&dev_priv->resource_lock);
 }
 
 static void vmw_resource_release(struct kref *kref)
@@ -73,10 +73,9 @@ static void vmw_resource_release(struct kref *kref)
        int id;
        struct idr *idr = &dev_priv->res_idr[res->func->res_type];
 
-       write_lock(&dev_priv->resource_lock);
-       res->avail = false;
+       spin_lock(&dev_priv->resource_lock);
        list_del_init(&res->lru_head);
-       write_unlock(&dev_priv->resource_lock);
+       spin_unlock(&dev_priv->resource_lock);
        if (res->backup) {
                struct ttm_buffer_object *bo = &res->backup->base;
 
@@ -108,10 +107,10 @@ static void vmw_resource_release(struct kref *kref)
        else
                kfree(res);
 
-       write_lock(&dev_priv->resource_lock);
+       spin_lock(&dev_priv->resource_lock);
        if (id != -1)
                idr_remove(idr, id);
-       write_unlock(&dev_priv->resource_lock);
+       spin_unlock(&dev_priv->resource_lock);
 }
 
 void vmw_resource_unreference(struct vmw_resource **p_res)
@@ -140,13 +139,13 @@ int vmw_resource_alloc_id(struct vmw_resource *res)
        BUG_ON(res->id != -1);
 
        idr_preload(GFP_KERNEL);
-       write_lock(&dev_priv->resource_lock);
+       spin_lock(&dev_priv->resource_lock);
 
        ret = idr_alloc(idr, res, 1, 0, GFP_NOWAIT);
        if (ret >= 0)
                res->id = ret;
 
-       write_unlock(&dev_priv->resource_lock);
+       spin_unlock(&dev_priv->resource_lock);
        idr_preload_end();
        return ret < 0 ? ret : 0;
 }
@@ -170,7 +169,6 @@ int vmw_resource_init(struct vmw_private *dev_priv, struct vmw_resource *res,
        kref_init(&res->kref);
        res->hw_destroy = NULL;
        res->res_free = res_free;
-       res->avail = false;
        res->dev_priv = dev_priv;
        res->func = func;
        INIT_LIST_HEAD(&res->lru_head);
@@ -187,28 +185,6 @@ int vmw_resource_init(struct vmw_private *dev_priv, struct vmw_resource *res,
                return vmw_resource_alloc_id(res);
 }
 
-/**
- * vmw_resource_activate
- *
- * @res:        Pointer to the newly created resource
- * @hw_destroy: Destroy function. NULL if none.
- *
- * Activate a resource after the hardware has been made aware of it.
- * Set tye destroy function to @destroy. Typically this frees the
- * resource and destroys the hardware resources associated with it.
- * Activate basically means that the function vmw_resource_lookup will
- * find it.
- */
-void vmw_resource_activate(struct vmw_resource *res,
-                          void (*hw_destroy) (struct vmw_resource *))
-{
-       struct vmw_private *dev_priv = res->dev_priv;
-
-       write_lock(&dev_priv->resource_lock);
-       res->avail = true;
-       res->hw_destroy = hw_destroy;
-       write_unlock(&dev_priv->resource_lock);
-}
 
 /**
  * vmw_user_resource_lookup_handle - lookup a struct resource from a
@@ -243,15 +219,10 @@ int vmw_user_resource_lookup_handle(struct vmw_private *dev_priv,
                goto out_bad_resource;
 
        res = converter->base_obj_to_res(base);
-
-       read_lock(&dev_priv->resource_lock);
-       if (!res->avail || res->res_free != converter->res_free) {
-               read_unlock(&dev_priv->resource_lock);
+       if (res->res_free != converter->res_free)
                goto out_bad_resource;
-       }
 
        kref_get(&res->kref);
-       read_unlock(&dev_priv->resource_lock);
 
        *p_res = res;
        ret = 0;
@@ -422,10 +393,10 @@ void vmw_resource_unreserve(struct vmw_resource *res,
        if (!res->func->may_evict || res->id == -1 || res->pin_count)
                return;
 
-       write_lock(&dev_priv->resource_lock);
+       spin_lock(&dev_priv->resource_lock);
        list_add_tail(&res->lru_head,
                      &res->dev_priv->res_lru[res->func->res_type]);
-       write_unlock(&dev_priv->resource_lock);
+       spin_unlock(&dev_priv->resource_lock);
 }
 
 /**
@@ -504,9 +475,9 @@ int vmw_resource_reserve(struct vmw_resource *res, bool interruptible,
        struct vmw_private *dev_priv = res->dev_priv;
        int ret;
 
-       write_lock(&dev_priv->resource_lock);
+       spin_lock(&dev_priv->resource_lock);
        list_del_init(&res->lru_head);
-       write_unlock(&dev_priv->resource_lock);
+       spin_unlock(&dev_priv->resource_lock);
 
        if (res->func->needs_backup && res->backup == NULL &&
            !no_backup) {
@@ -619,12 +590,12 @@ int vmw_resource_validate(struct vmw_resource *res, bool intr)
                if (likely(ret != -EBUSY))
                        break;
 
-               write_lock(&dev_priv->resource_lock);
+               spin_lock(&dev_priv->resource_lock);
                if (list_empty(lru_list) || !res->func->may_evict) {
                        DRM_ERROR("Out of device device resources "
                                  "for %s.\n", res->func->type_name);
                        ret = -EBUSY;
-                       write_unlock(&dev_priv->resource_lock);
+                       spin_unlock(&dev_priv->resource_lock);
                        break;
                }
 
@@ -633,14 +604,14 @@ int vmw_resource_validate(struct vmw_resource *res, bool intr)
                                          lru_head));
                list_del_init(&evict_res->lru_head);
 
-               write_unlock(&dev_priv->resource_lock);
+               spin_unlock(&dev_priv->resource_lock);
 
                /* Trylock backup buffers with a NULL ticket. */
                ret = vmw_resource_do_evict(NULL, evict_res, intr);
                if (unlikely(ret != 0)) {
-                       write_lock(&dev_priv->resource_lock);
+                       spin_lock(&dev_priv->resource_lock);
                        list_add_tail(&evict_res->lru_head, lru_list);
-                       write_unlock(&dev_priv->resource_lock);
+                       spin_unlock(&dev_priv->resource_lock);
                        if (ret == -ERESTARTSYS ||
                            ++err_count > VMW_RES_EVICT_ERR_COUNT) {
                                vmw_resource_unreference(&evict_res);
@@ -822,7 +793,7 @@ static void vmw_resource_evict_type(struct vmw_private *dev_priv,
        struct ww_acquire_ctx ticket;
 
        do {
-               write_lock(&dev_priv->resource_lock);
+               spin_lock(&dev_priv->resource_lock);
 
                if (list_empty(lru_list))
                        goto out_unlock;
@@ -831,14 +802,14 @@ static void vmw_resource_evict_type(struct vmw_private *dev_priv,
                        list_first_entry(lru_list, struct vmw_resource,
                                         lru_head));
                list_del_init(&evict_res->lru_head);
-               write_unlock(&dev_priv->resource_lock);
+               spin_unlock(&dev_priv->resource_lock);
 
                /* Wait lock backup buffers with a ticket. */
                ret = vmw_resource_do_evict(&ticket, evict_res, false);
                if (unlikely(ret != 0)) {
-                       write_lock(&dev_priv->resource_lock);
+                       spin_lock(&dev_priv->resource_lock);
                        list_add_tail(&evict_res->lru_head, lru_list);
-                       write_unlock(&dev_priv->resource_lock);
+                       spin_unlock(&dev_priv->resource_lock);
                        if (++err_count > VMW_RES_EVICT_ERR_COUNT) {
                                vmw_resource_unreference(&evict_res);
                                return;
@@ -849,7 +820,7 @@ static void vmw_resource_evict_type(struct vmw_private *dev_priv,
        } while (1);
 
 out_unlock:
-       write_unlock(&dev_priv->resource_lock);
+       spin_unlock(&dev_priv->resource_lock);
 }
 
 /**
index a8c1c5ebd71d39a0f2235d08ecd3e552ff0fcf8f..6453708682963c54807fb1130d49901ed90497b4 100644 (file)
@@ -120,8 +120,6 @@ int vmw_resource_init(struct vmw_private *dev_priv, struct vmw_resource *res,
                      bool delay_id,
                      void (*res_free) (struct vmw_resource *res),
                      const struct vmw_res_func *func);
-void vmw_resource_activate(struct vmw_resource *res,
-                          void (*hw_destroy) (struct vmw_resource *));
 int
 vmw_simple_resource_create_ioctl(struct drm_device *dev,
                                 void *data,
index e03431aef3d0dc13b7c1630c5d076156d293dfed..c72b4351176aa625e4269a60724450b6889e7c5c 100644 (file)
@@ -186,7 +186,7 @@ static int vmw_gb_shader_init(struct vmw_private *dev_priv,
        shader->num_input_sig = num_input_sig;
        shader->num_output_sig = num_output_sig;
 
-       vmw_resource_activate(res, vmw_hw_shader_destroy);
+       res->hw_destroy = vmw_hw_shader_destroy;
        return 0;
 }
 
@@ -656,7 +656,7 @@ int vmw_dx_shader_add(struct vmw_cmdbuf_res_manager *man,
                goto out_resource_init;
 
        res->id = shader->id;
-       vmw_resource_activate(res, vmw_hw_shader_destroy);
+       res->hw_destroy = vmw_hw_shader_destroy;
 
 out_resource_init:
        vmw_resource_unreference(&res);
index 6ebc5affde1476587636d5312514fa32d3e5f3dd..3bd60f7a9d6d72fc9f72c6c483acf7136908eb32 100644 (file)
@@ -81,7 +81,7 @@ static int vmw_simple_resource_init(struct vmw_private *dev_priv,
                return ret;
        }
 
-       vmw_resource_activate(&simple->res, simple->func->hw_destroy);
+       simple->res.hw_destroy = simple->func->hw_destroy;
 
        return 0;
 }
index a01de4845eb713e97f0a422f2fec9c11c66ada4b..aaabb87ac3af38b2488abcc7e5aa7f4ac3dabea6 100644 (file)
@@ -386,7 +386,7 @@ int vmw_view_add(struct vmw_cmdbuf_res_manager *man,
                goto out_resource_init;
 
        res->id = view->view_id;
-       vmw_resource_activate(res, vmw_hw_view_destroy);
+       res->hw_destroy = vmw_hw_view_destroy;
 
 out_resource_init:
        vmw_resource_unreference(&res);
index e125233e074bf82a1128543ca5c8f9fd2b28604c..bd4cf995089cad39c624f54a1816d12b8a6dd838 100644 (file)
@@ -614,7 +614,7 @@ static int vmw_surface_init(struct vmw_private *dev_priv,
         */
 
        INIT_LIST_HEAD(&srf->view_list);
-       vmw_resource_activate(res, vmw_hw_surface_destroy);
+       res->hw_destroy = vmw_hw_surface_destroy;
        return ret;
 }