From 2ea0c88aed47af13b7f278e4b1d7c1a8c3868cc4 Mon Sep 17 00:00:00 2001 From: Wenkui Date: Thu, 5 Dec 2024 06:59:59 +0000 Subject: [PATCH] DRM[i915]: fix i915 crash during reboot stress test Use drm_release with global spinlock to make sure memtrack file create/close is serialization, and if sysfs_create_bin_file return file existed error, need to return 0 to let open drm process move forward Tracked-On: OAM-128000 Signed-off-by: Kui Wen --- drivers/gpu/drm/i915/gem/i915_gem_context.c | 3 +++ drivers/gpu/drm/i915/i915_driver.c | 2 +- drivers/gpu/drm/i915/i915_sysfs.c | 12 +++++------- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c b/drivers/gpu/drm/i915/gem/i915_gem_context.c index e38f06a6e56eb..6e20e242cb02b 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_context.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c @@ -1711,6 +1711,9 @@ static void gem_context_register(struct i915_gem_context *ctx, snprintf(ctx->name, sizeof(ctx->name), "%s[%d]", current->comm, pid_nr(ctx->pid)); + if (ctx->client == NULL) + return ; + spin_lock(&ctx->client->ctx_lock); list_add_tail_rcu(&ctx->client_link, &ctx->client->ctx_list); spin_unlock(&ctx->client->ctx_lock); diff --git a/drivers/gpu/drm/i915/i915_driver.c b/drivers/gpu/drm/i915/i915_driver.c index bc615be11071f..81af5a0a1427a 100644 --- a/drivers/gpu/drm/i915/i915_driver.c +++ b/drivers/gpu/drm/i915/i915_driver.c @@ -1772,7 +1772,7 @@ const struct dev_pm_ops i915_pm_ops = { static const struct file_operations i915_driver_fops = { .owner = THIS_MODULE, .open = drm_open, - .release = drm_release_noglobal, + .release = drm_release, .unlocked_ioctl = drm_ioctl, .mmap = i915_gem_mmap, .poll = drm_poll, diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c index 483a78f5e2f98..9c42942614102 100644 --- a/drivers/gpu/drm/i915/i915_sysfs.c +++ b/drivers/gpu/drm/i915/i915_sysfs.c @@ -407,7 +407,7 @@ int i915_gem_create_sysfs_file_entry(struct drm_device *dev, struct drm_i915_file_private *file_priv_local = file_local->driver_priv; - if (pid_nr(file_priv->tgid) == pid_nr(file_priv_local->tgid)) { + if ((pid_nr(file_priv->tgid) == pid_nr(file_priv_local->tgid)) && (file_priv_local->obj_attr != NULL)) { file_priv->obj_attr = file_priv_local->obj_attr; mutex_unlock(&dev->filelist_mutex); return 0; @@ -447,6 +447,8 @@ int i915_gem_create_sysfs_file_entry(struct drm_device *dev, DRM_ERROR( "sysfs tgid file setup failed. tgid=%d, process:%s, ret:%d\n", pid_nr(file_priv->tgid), file_priv->process_name, ret); + if (ret == -EEXIST) + ret = 0; goto out_attr_priv; } @@ -486,16 +488,15 @@ void i915_gem_remove_sysfs_file_entry(struct drm_device *dev, } mutex_unlock(&dev->filelist_mutex); - mutex_lock(&drm_global_mutex); if (open_count == 1) { struct i915_gem_file_attr_priv *attr_priv; if (file_priv->obj_attr == NULL) - goto out; + return; attr_priv = file_priv->obj_attr->private; if (attr_priv == NULL) - goto out; + return; sysfs_remove_bin_file(&dev_priv->memtrack_kobj, file_priv->obj_attr); @@ -506,9 +507,6 @@ void i915_gem_remove_sysfs_file_entry(struct drm_device *dev, kfree(file_priv->obj_attr); file_priv->obj_attr = NULL; } - -out: - mutex_unlock(&drm_global_mutex); } static struct bin_attribute i915_gem_client_state_attr = {