msm: kgsl: Compare pid pointer instead of TGID for a new process

There is a possibility of sharing process_private between two unrelated
processes due to PID wrapping. In kgsl_process_private_new(), instead
of checking numeric TGID, compare the unique pid pointer of the current
process with that of the existing processes in kgsl process list to
allow sharing of process_private data judiciously. Also, in all required
functions get TGID/PID of a process from its struct pid.

Change-Id: I0e3d5d79275cdb3f3c304fb36322ad56b0d0b227
Signed-off-by: Archana Sriram <apsrir@codeaurora.org>
This commit is contained in:
Archana Sriram
2020-10-16 07:26:30 +05:30
parent ccbf386326
commit d35d5ad9ea
9 changed files with 38 additions and 34 deletions

View File

@@ -262,7 +262,7 @@ static int ctx_print(struct seq_file *s, void *unused)
kgsl_context_type(drawctxt->type),
drawctxt->base.priority,
drawctxt->base.proc_priv->comm,
drawctxt->base.proc_priv->pid,
pid_nr(drawctxt->base.proc_priv->pid),
drawctxt->base.tid);
seq_puts(s, "flags: ");

View File

@@ -300,7 +300,7 @@ static void _retire_timestamp(struct kgsl_drawobj *drawobj)
info.timestamp = drawobj->timestamp;
msm_perf_events_update(MSM_PERF_GFX, MSM_PERF_RETIRED,
context->proc_priv->pid,
pid_nr(context->proc_priv->pid),
context->id, drawobj->timestamp);
/*
@@ -696,7 +696,7 @@ static int sendcmd(struct adreno_device *adreno_dev,
info.gmu_dispatch_queue = -1;
msm_perf_events_update(MSM_PERF_GFX, MSM_PERF_SUBMIT,
context->proc_priv->pid,
pid_nr(context->proc_priv->pid),
context->id, drawobj->timestamp);
trace_adreno_cmdbatch_submitted(drawobj, &info,
@@ -1219,7 +1219,7 @@ static void _queue_drawobj(struct adreno_context *drawctxt,
ADRENO_CONTEXT_DRAWQUEUE_SIZE;
drawctxt->queued++;
msm_perf_events_update(MSM_PERF_GFX, MSM_PERF_QUEUE,
context->proc_priv->pid,
pid_nr(context->proc_priv->pid),
context->id, drawobj->timestamp);
trace_adreno_cmdbatch_queued(drawobj, drawctxt->queued);
}
@@ -1643,7 +1643,7 @@ static inline const char *_kgsl_context_comm(struct kgsl_context *context)
#define pr_fault(_d, _c, fmt, args...) \
dev_err((_d)->dev, "%s[%d]: " fmt, \
_kgsl_context_comm((_c)->context), \
(_c)->context->proc_priv->pid, ##args)
pid_nr((_c)->context->proc_priv->pid), ##args)
static void adreno_fault_header(struct kgsl_device *device,
@@ -2321,7 +2321,7 @@ static void retire_cmdobj(struct adreno_device *adreno_dev,
info.eop = end;
msm_perf_events_update(MSM_PERF_GFX, MSM_PERF_RETIRED,
context->proc_priv->pid,
pid_nr(context->proc_priv->pid),
context->id, drawobj->timestamp);
/*

View File

@@ -131,7 +131,7 @@ static int _build_pre_ib_cmds(struct adreno_device *adreno_dev,
ibcmds += _ib_cmd_mem_write(adreno_dev, ibcmds, gpuaddr + data_offset,
drawctxt->base.id, &data_offset);
ibcmds += _ib_cmd_mem_write(adreno_dev, ibcmds, gpuaddr + data_offset,
drawctxt->base.proc_priv->pid, &data_offset);
pid_nr(drawctxt->base.proc_priv->pid), &data_offset);
ibcmds += _ib_cmd_mem_write(adreno_dev, ibcmds, gpuaddr + data_offset,
drawctxt->base.tid, &data_offset);
ibcmds += _ib_cmd_mem_write(adreno_dev, ibcmds, gpuaddr + data_offset,

View File

@@ -572,7 +572,7 @@ int kgsl_context_init(struct kgsl_device_private *dev_priv,
if (atomic_read(&proc_priv->ctxt_count) > KGSL_MAX_CONTEXTS_PER_PROC) {
dev_err(device->dev,
"Per process context limit reached for pid %u\n",
dev_priv->process_priv->pid);
pid_nr(dev_priv->process_priv->pid));
spin_unlock(&proc_priv->ctxt_count_lock);
return -ENOSPC;
}
@@ -792,6 +792,7 @@ static void kgsl_destroy_process_private(struct kref *kref)
struct kgsl_process_private *private = container_of(kref,
struct kgsl_process_private, refcount);
put_pid(private->pid);
idr_destroy(&private->mem_idr);
idr_destroy(&private->syncsource_idr);
@@ -821,7 +822,7 @@ struct kgsl_process_private *kgsl_process_private_find(pid_t pid)
spin_lock(&kgsl_driver.proclist_lock);
list_for_each_entry(p, &kgsl_driver.process_list, list) {
if (p->pid == pid) {
if (pid_nr(p->pid) == pid) {
if (kgsl_process_private_get(p))
private = p;
break;
@@ -836,13 +837,15 @@ static struct kgsl_process_private *kgsl_process_private_new(
struct kgsl_device *device)
{
struct kgsl_process_private *private;
pid_t tgid = task_tgid_nr(current);
struct pid *cur_pid = get_task_pid(current->group_leader, PIDTYPE_PID);
/* Search in the process list */
list_for_each_entry(private, &kgsl_driver.process_list, list) {
if (private->pid == tgid) {
if (!kgsl_process_private_get(private))
if (private->pid == cur_pid) {
if (!kgsl_process_private_get(private)) {
put_pid(cur_pid);
private = ERR_PTR(-EINVAL);
}
return private;
}
}
@@ -854,7 +857,7 @@ static struct kgsl_process_private *kgsl_process_private_new(
kref_init(&private->refcount);
private->pid = tgid;
private->pid = cur_pid;
get_task_comm(private->comm, current->group_leader);
spin_lock_init(&private->mem_lock);
@@ -865,12 +868,13 @@ static struct kgsl_process_private *kgsl_process_private_new(
idr_init(&private->syncsource_idr);
/* Allocate a pagetable for the new process object */
private->pagetable = kgsl_mmu_getpagetable(&device->mmu, tgid);
private->pagetable = kgsl_mmu_getpagetable(&device->mmu, pid_nr(cur_pid));
if (IS_ERR(private->pagetable)) {
int err = PTR_ERR(private->pagetable);
idr_destroy(&private->mem_idr);
idr_destroy(&private->syncsource_idr);
put_pid(private->pid);
kfree(private);
private = ERR_PTR(err);
@@ -2065,7 +2069,7 @@ long gpumem_free_entry(struct kgsl_mem_entry *entry)
return -EBUSY;
trace_kgsl_mem_free(entry);
kgsl_memfree_add(entry->priv->pid,
kgsl_memfree_add(pid_nr(entry->priv->pid),
entry->memdesc.pagetable ?
entry->memdesc.pagetable->name : 0,
entry->memdesc.gpuaddr, entry->memdesc.size,
@@ -2088,7 +2092,7 @@ static void gpumem_free_func(struct kgsl_device *device,
/* Free the memory for all event types */
trace_kgsl_mem_timestamp_free(device, entry, KGSL_CONTEXT_ID(context),
timestamp, 0);
kgsl_memfree_add(entry->priv->pid,
kgsl_memfree_add(pid_nr(entry->priv->pid),
entry->memdesc.pagetable ?
entry->memdesc.pagetable->name : 0,
entry->memdesc.gpuaddr, entry->memdesc.size,
@@ -2188,7 +2192,7 @@ static bool gpuobj_free_fence_func(void *priv)
struct kgsl_mem_entry *entry = priv;
trace_kgsl_mem_free(entry);
kgsl_memfree_add(entry->priv->pid,
kgsl_memfree_add(pid_nr(entry->priv->pid),
entry->memdesc.pagetable ?
entry->memdesc.pagetable->name : 0,
entry->memdesc.gpuaddr, entry->memdesc.size,
@@ -3933,14 +3937,14 @@ kgsl_get_unmapped_area(struct file *file, unsigned long addr,
if (IS_ERR_VALUE(val))
dev_err_ratelimited(device->dev,
"get_unmapped_area: pid %d addr %lx pgoff %lx len %ld failed error %d\n",
private->pid, addr, pgoff, len,
pid_nr(private->pid), addr, pgoff, len,
(int) val);
} else {
val = get_svm_unmapped_area(file, entry, addr, len, flags);
if (IS_ERR_VALUE(val))
dev_err_ratelimited(device->dev,
"_get_svm_area: pid %d addr %lx pgoff %lx len %ld failed error %d\n",
private->pid, addr, pgoff, len,
pid_nr(private->pid), addr, pgoff, len,
(int) val);
}

View File

@@ -339,7 +339,7 @@ void kgsl_process_init_debugfs(struct kgsl_process_private *private)
unsigned char name[16];
struct dentry *dentry;
snprintf(name, sizeof(name), "%d", private->pid);
snprintf(name, sizeof(name), "%d", pid_nr(private->pid));
private->debug_root = debugfs_create_dir(name, proc_d_debugfs);
@@ -359,7 +359,7 @@ void kgsl_process_init_debugfs(struct kgsl_process_private *private)
}
dentry = debugfs_create_file("mem", 0444, private->debug_root,
(void *) ((unsigned long) private->pid), &process_mem_fops);
(void *) ((unsigned long) pid_nr(private->pid)), &process_mem_fops);
if (IS_ERR_OR_NULL(dentry))
WARN((dentry == NULL),

View File

@@ -403,13 +403,13 @@ struct kgsl_context {
#define pr_context(_d, _c, fmt, args...) \
dev_err((_d)->dev, "%s[%d]: " fmt, \
_context_comm((_c)), \
(_c)->proc_priv->pid, ##args)
pid_nr((_c)->proc_priv->pid), ##args)
/**
* struct kgsl_process_private - Private structure for a KGSL process (across
* all devices)
* @priv: Internal flags, use KGSL_PROCESS_* values
* @pid: ID for the task owner of the process
* @pid: Identification structure for the task owner of the process
* @comm: task name of the process
* @mem_lock: Spinlock to protect the process memory lists
* @refcount: kref object for reference counting the process
@@ -427,7 +427,7 @@ struct kgsl_context {
*/
struct kgsl_process_private {
unsigned long priv;
pid_t pid;
struct pid *pid;
char comm[TASK_COMM_LEN];
spinlock_t mem_lock;
struct kref refcount;

View File

@@ -466,7 +466,7 @@ static void _get_entries(struct kgsl_process_private *private,
prev->flags = p->memdesc.flags;
prev->priv = p->memdesc.priv;
prev->pending_free = p->pending_free;
prev->pid = private->pid;
prev->pid = pid_nr(private->pid);
kgsl_get_memory_usage(prev->name, sizeof(prev->name),
prev->flags);
}
@@ -477,7 +477,7 @@ static void _get_entries(struct kgsl_process_private *private,
next->flags = n->memdesc.flags;
next->priv = n->memdesc.priv;
next->pending_free = n->pending_free;
next->pid = private->pid;
next->pid = pid_nr(private->pid);
kgsl_get_memory_usage(next->name, sizeof(next->name),
next->flags);
}
@@ -633,7 +633,7 @@ static int kgsl_iommu_fault_handler(struct iommu_domain *domain,
private = kgsl_iommu_get_process(ptbase);
if (private) {
pid = private->pid;
pid = pid_nr(private->pid);
comm = private->comm;
}

View File

@@ -242,9 +242,9 @@ void kgsl_process_init_sysfs(struct kgsl_device *device,
kgsl_process_private_get(private);
if (kobject_init_and_add(&private->kobj, &ktype_mem_entry,
kgsl_driver.prockobj, "%d", private->pid)) {
kgsl_driver.prockobj, "%d", pid_nr(private->pid))) {
dev_err(device->dev, "Unable to add sysfs for process %d\n",
private->pid);
pid_nr(private->pid));
return;
}
@@ -259,7 +259,7 @@ void kgsl_process_init_sysfs(struct kgsl_device *device,
if (ret)
dev_err(device->dev,
"Unable to create sysfs files for process %d\n",
private->pid);
pid_nr(private->pid));
}
for (i = 0; i < ARRAY_SIZE(debug_memstats); i++) {

View File

@@ -440,7 +440,7 @@ TRACE_EVENT(kgsl_mem_alloc,
TP_fast_assign(
__entry->gpuaddr = mem_entry->memdesc.gpuaddr;
__entry->size = mem_entry->memdesc.size;
__entry->tgid = mem_entry->priv->pid;
__entry->tgid = pid_nr(mem_entry->priv->pid);
kgsl_get_memory_usage(__entry->usage, sizeof(__entry->usage),
mem_entry->memdesc.flags);
__entry->id = mem_entry->id;
@@ -533,7 +533,7 @@ TRACE_EVENT(kgsl_mem_map,
__entry->size = mem_entry->memdesc.size;
__entry->fd = fd;
__entry->type = kgsl_memdesc_usermem_type(&mem_entry->memdesc);
__entry->tgid = mem_entry->priv->pid;
__entry->tgid = pid_nr(mem_entry->priv->pid);
kgsl_get_memory_usage(__entry->usage, sizeof(__entry->usage),
mem_entry->memdesc.flags);
__entry->id = mem_entry->id;
@@ -568,7 +568,7 @@ TRACE_EVENT(kgsl_mem_free,
__entry->gpuaddr = mem_entry->memdesc.gpuaddr;
__entry->size = mem_entry->memdesc.size;
__entry->type = kgsl_memdesc_usermem_type(&mem_entry->memdesc);
__entry->tgid = mem_entry->priv->pid;
__entry->tgid = pid_nr(mem_entry->priv->pid);
kgsl_get_memory_usage(__entry->usage, sizeof(__entry->usage),
mem_entry->memdesc.flags);
__entry->id = mem_entry->id;
@@ -603,7 +603,7 @@ TRACE_EVENT(kgsl_mem_sync_cache,
__entry->gpuaddr = mem_entry->memdesc.gpuaddr;
kgsl_get_memory_usage(__entry->usage, sizeof(__entry->usage),
mem_entry->memdesc.flags);
__entry->tgid = mem_entry->priv->pid;
__entry->tgid = pid_nr(mem_entry->priv->pid);
__entry->id = mem_entry->id;
__entry->op = op;
__entry->offset = offset;