@@ -16,6 +16,7 @@
#include <linux/soc/qcom/mdt_loader.h>
#include <linux/nvmem-consumer.h>
#include <soc/qcom/ocmem.h>
+#include <drm/drm_file.h>
#include "adreno_gpu.h"
#include "a6xx_gpu.h"
#include "msm_gem.h"
@@ -398,7 +399,8 @@ int adreno_set_param(struct msm_gpu *gpu, struct msm_file_private *ctx,
switch (param) {
case MSM_PARAM_COMM:
case MSM_PARAM_CMDLINE: {
- char *str, **paramp;
+ char *str, *str2, **paramp;
+ struct drm_file *file = ctx->file;
str = kmalloc(len + 1, GFP_KERNEL);
if (!str)
@@ -412,6 +414,13 @@ int adreno_set_param(struct msm_gpu *gpu, struct msm_file_private *ctx,
/* Ensure string is null terminated: */
str[len] = '\0';
+ /*
+ * We need a 2nd copy for drm_file.. this copy can't replace
+ * our internal copy in the ctx, because we may need it for
+ * recovery/devcoredump after the file is already closed.
+ */
+ str2 = kstrdup(str, GFP_KERNEL);
+
mutex_lock(&gpu->lock);
if (param == MSM_PARAM_COMM) {
@@ -425,6 +434,19 @@ int adreno_set_param(struct msm_gpu *gpu, struct msm_file_private *ctx,
mutex_unlock(&gpu->lock);
+ mutex_lock(&file->override_lock);
+
+ if (param == MSM_PARAM_COMM) {
+ paramp = &file->override_comm;
+ } else {
+ paramp = &file->override_cmdline;
+ }
+
+ kfree(*paramp);
+ *paramp = str2;
+
+ mutex_unlock(&file->override_lock);
+
return 0;
}
case MSM_PARAM_SYSPROF:
@@ -581,6 +581,7 @@ static int context_init(struct drm_device *dev, struct drm_file *file)
rwlock_init(&ctx->queuelock);
kref_init(&ctx->ref);
+ ctx->file = file;
msm_submitqueue_init(dev, ctx);
ctx->aspace = msm_gpu_create_private_address_space(priv->gpu, current);
@@ -603,6 +604,7 @@ static int msm_open(struct drm_device *dev, struct drm_file *file)
static void context_close(struct msm_file_private *ctx)
{
+ ctx->file = NULL;
msm_submitqueue_close(ctx);
msm_file_private_put(ctx);
}
@@ -359,6 +359,16 @@ struct msm_file_private {
struct kref ref;
int seqno;
+ /**
+ * @file: link back to the associated drm_file
+ *
+ * Note that msm_file_private can outlive the drm_file, ie.
+ * after the drm_file is closed but before jobs submitted have
+ * been cleaned up. After the drm_file is closed this will be
+ * NULL.
+ */
+ struct drm_file *file;
+
/**
* sysprof:
*