OSDN Git Service

msm: kgsl: Limit the maximum number of contexts
authorHarshdeep Dhatt <hdhatt@codeaurora.org>
Tue, 12 Dec 2017 21:56:20 +0000 (14:56 -0700)
committerGerrit - the friendly Code Review server <code-review@localhost>
Mon, 5 Mar 2018 09:17:09 +0000 (01:17 -0800)
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 <hdhatt@codeaurora.org>
Signed-off-by: Archana Obannagari <aobann@codeaurora.org>
drivers/gpu/msm/kgsl.c
drivers/gpu/msm/kgsl.h
drivers/gpu/msm/kgsl_device.h

index cc3e79d..ce129c2 100644 (file)
@@ -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;
        }
index ece8396..a486d9a 100644 (file)
@@ -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)
index 64dd45a..b6c787e 100644 (file)
@@ -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;
 };
 
 /**