From 3f5a22eca9bc17152794aa45a79551fbe2579ae3 Mon Sep 17 00:00:00 2001 From: Harshdeep Dhatt Date: Tue, 12 Dec 2017 14:56:20 -0700 Subject: [PATCH] msm: kgsl: Limit the maximum number of contexts Enforce a limit of 200 contexts per process. This is done so that a process cannot use up all the available contexts and prevent other processes from starving. Change-Id: I6eda123128381a213315561cd42335e0944f1f55 Signed-off-by: Harshdeep Dhatt Signed-off-by: Archana Obannagari --- drivers/gpu/msm/kgsl.c | 14 +++++++++++++- drivers/gpu/msm/kgsl.h | 1 + drivers/gpu/msm/kgsl_device.h | 4 +++- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c index cc3e79dc29bf..ce129c27fddd 100644 --- a/drivers/gpu/msm/kgsl.c +++ b/drivers/gpu/msm/kgsl.c @@ -530,6 +530,16 @@ int kgsl_context_init(struct kgsl_device_private *dev_priv, struct kgsl_device *device = dev_priv->device; char name[64]; int ret = 0, id; + struct kgsl_process_private *proc_priv = dev_priv->process_priv; + + if (atomic_read(&proc_priv->ctxt_count) > KGSL_MAX_CONTEXTS_PER_PROC) { + KGSL_DRV_ERR(device, + "Per process context limit reached for pid %u", + dev_priv->process_priv->pid); + return -ENOSPC; + } + + atomic_inc(&proc_priv->ctxt_count); id = _kgsl_get_context_id(device); if (id == -ENOSPC) { @@ -548,7 +558,7 @@ int kgsl_context_init(struct kgsl_device_private *dev_priv, KGSL_DRV_INFO(device, "cannot have more than %zu contexts due to memstore limitation\n", KGSL_MEMSTORE_MAX); - + atomic_dec(&proc_priv->ctxt_count); return id; } @@ -579,6 +589,7 @@ int kgsl_context_init(struct kgsl_device_private *dev_priv, out: if (ret) { + atomic_dec(&proc_priv->ctxt_count); write_lock(&device->context_lock); idr_remove(&dev_priv->device->context_idr, id); write_unlock(&device->context_lock); @@ -662,6 +673,7 @@ kgsl_context_destroy(struct kref *kref) device->pwrctrl.constraint.type = KGSL_CONSTRAINT_NONE; } + atomic_dec(&context->proc_priv->ctxt_count); idr_remove(&device->context_idr, context->id); context->id = KGSL_CONTEXT_INVALID; } diff --git a/drivers/gpu/msm/kgsl.h b/drivers/gpu/msm/kgsl.h index ece8396acb68..a486d9a86f9d 100644 --- a/drivers/gpu/msm/kgsl.h +++ b/drivers/gpu/msm/kgsl.h @@ -56,6 +56,7 @@ #define KGSL_PRIORITY_MAX_RB_LEVELS 4 #define KGSL_MEMSTORE_MAX (KGSL_MEMSTORE_SIZE / \ sizeof(struct kgsl_devmemstore) - 1 - KGSL_PRIORITY_MAX_RB_LEVELS) +#define KGSL_MAX_CONTEXTS_PER_PROC 200 #define MEMSTORE_RB_OFFSET(rb, field) \ KGSL_MEMSTORE_OFFSET(((rb)->id + KGSL_MEMSTORE_MAX), field) diff --git a/drivers/gpu/msm/kgsl_device.h b/drivers/gpu/msm/kgsl_device.h index 64dd45a30612..b6c787ecac36 100644 --- a/drivers/gpu/msm/kgsl_device.h +++ b/drivers/gpu/msm/kgsl_device.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2002,2007-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2002,2007-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -417,6 +417,7 @@ struct kgsl_context { * @syncsource_idr: sync sources created by this process * @syncsource_lock: Spinlock to protect the syncsource idr * @fd_count: Counter for the number of FDs for this process + * @ctxt_count: Count for the number of contexts for this process */ struct kgsl_process_private { unsigned long priv; @@ -436,6 +437,7 @@ struct kgsl_process_private { struct idr syncsource_idr; spinlock_t syncsource_lock; int fd_count; + atomic_t ctxt_count; }; /** -- 2.11.0