提交 eb9bcbdc 编写于 作者: B Ben Skeggs

drm/nouveau: fix gpuobj refcount to use atomics

Reviewed-by: NFrancisco Jerez <currojerez@riseup.net>
Signed-off-by: NBen Skeggs <bskeggs@redhat.com>
上级 dac79008
...@@ -137,6 +137,7 @@ enum nouveau_flags { ...@@ -137,6 +137,7 @@ enum nouveau_flags {
#define NVOBJ_FLAG_ZERO_FREE (1 << 2) #define NVOBJ_FLAG_ZERO_FREE (1 << 2)
struct nouveau_gpuobj { struct nouveau_gpuobj {
struct drm_device *dev; struct drm_device *dev;
struct kref refcount;
struct list_head list; struct list_head list;
struct drm_mm_node *im_pramin; struct drm_mm_node *im_pramin;
...@@ -145,7 +146,6 @@ struct nouveau_gpuobj { ...@@ -145,7 +146,6 @@ struct nouveau_gpuobj {
int im_bound; int im_bound;
uint32_t flags; uint32_t flags;
int refcount;
u32 size; u32 size;
u32 pinst; u32 pinst;
......
...@@ -90,7 +90,7 @@ nouveau_gpuobj_new(struct drm_device *dev, struct nouveau_channel *chan, ...@@ -90,7 +90,7 @@ nouveau_gpuobj_new(struct drm_device *dev, struct nouveau_channel *chan,
NV_DEBUG(dev, "gpuobj %p\n", gpuobj); NV_DEBUG(dev, "gpuobj %p\n", gpuobj);
gpuobj->dev = dev; gpuobj->dev = dev;
gpuobj->flags = flags; gpuobj->flags = flags;
gpuobj->refcount = 1; kref_init(&gpuobj->refcount);
gpuobj->size = size; gpuobj->size = size;
list_add_tail(&gpuobj->list, &dev_priv->gpuobj_list); list_add_tail(&gpuobj->list, &dev_priv->gpuobj_list);
...@@ -198,25 +198,15 @@ void ...@@ -198,25 +198,15 @@ void
nouveau_gpuobj_late_takedown(struct drm_device *dev) nouveau_gpuobj_late_takedown(struct drm_device *dev)
{ {
struct drm_nouveau_private *dev_priv = dev->dev_private; struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_gpuobj *gpuobj = NULL;
struct list_head *entry, *tmp;
NV_DEBUG(dev, "\n");
list_for_each_safe(entry, tmp, &dev_priv->gpuobj_list) {
gpuobj = list_entry(entry, struct nouveau_gpuobj, list);
NV_ERROR(dev, "gpuobj %p still exists at takedown, refs=%d\n", BUG_ON(!list_empty(&dev_priv->gpuobj_list));
gpuobj, gpuobj->refcount);
gpuobj->refcount = 1;
nouveau_gpuobj_ref(NULL, &gpuobj);
}
} }
static int static void
nouveau_gpuobj_del(struct nouveau_gpuobj *gpuobj) nouveau_gpuobj_del(struct kref *ref)
{ {
struct nouveau_gpuobj *gpuobj =
container_of(ref, struct nouveau_gpuobj, refcount);
struct drm_device *dev = gpuobj->dev; struct drm_device *dev = gpuobj->dev;
struct drm_nouveau_private *dev_priv = dev->dev_private; struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_engine *engine = &dev_priv->engine; struct nouveau_engine *engine = &dev_priv->engine;
...@@ -242,17 +232,16 @@ nouveau_gpuobj_del(struct nouveau_gpuobj *gpuobj) ...@@ -242,17 +232,16 @@ nouveau_gpuobj_del(struct nouveau_gpuobj *gpuobj)
list_del(&gpuobj->list); list_del(&gpuobj->list);
kfree(gpuobj); kfree(gpuobj);
return 0;
} }
void void
nouveau_gpuobj_ref(struct nouveau_gpuobj *ref, struct nouveau_gpuobj **ptr) nouveau_gpuobj_ref(struct nouveau_gpuobj *ref, struct nouveau_gpuobj **ptr)
{ {
if (ref) if (ref)
ref->refcount++; kref_get(&ref->refcount);
if (*ptr && --(*ptr)->refcount == 0) if (*ptr)
nouveau_gpuobj_del(*ptr); kref_put(&(*ptr)->refcount, nouveau_gpuobj_del);
*ptr = ref; *ptr = ref;
} }
...@@ -275,7 +264,7 @@ nouveau_gpuobj_new_fake(struct drm_device *dev, u32 pinst, u64 vinst, ...@@ -275,7 +264,7 @@ nouveau_gpuobj_new_fake(struct drm_device *dev, u32 pinst, u64 vinst,
NV_DEBUG(dev, "gpuobj %p\n", gpuobj); NV_DEBUG(dev, "gpuobj %p\n", gpuobj);
gpuobj->dev = dev; gpuobj->dev = dev;
gpuobj->flags = flags; gpuobj->flags = flags;
gpuobj->refcount = 1; kref_init(&gpuobj->refcount);
gpuobj->size = size; gpuobj->size = size;
gpuobj->pinst = pinst; gpuobj->pinst = pinst;
gpuobj->cinst = 0xdeadbeef; gpuobj->cinst = 0xdeadbeef;
...@@ -561,7 +550,7 @@ nouveau_gpuobj_sw_new(struct nouveau_channel *chan, int class, ...@@ -561,7 +550,7 @@ nouveau_gpuobj_sw_new(struct nouveau_channel *chan, int class,
gpuobj->dev = chan->dev; gpuobj->dev = chan->dev;
gpuobj->engine = NVOBJ_ENGINE_SW; gpuobj->engine = NVOBJ_ENGINE_SW;
gpuobj->class = class; gpuobj->class = class;
gpuobj->refcount = 1; kref_init(&gpuobj->refcount);
gpuobj->cinst = 0x40; gpuobj->cinst = 0x40;
list_add_tail(&gpuobj->list, &dev_priv->gpuobj_list); list_add_tail(&gpuobj->list, &dev_priv->gpuobj_list);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册