From patchwork Thu Mar 22 14:14:58 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Praveen Paneri X-Patchwork-Id: 10301593 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 32766600F6 for ; Thu, 22 Mar 2018 14:01:07 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2621C28450 for ; Thu, 22 Mar 2018 14:01:07 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 18A4A2856A; Thu, 22 Mar 2018 14:01:07 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 7897728590 for ; Thu, 22 Mar 2018 14:01:06 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id A7C876EC2D; Thu, 22 Mar 2018 14:01:00 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by gabe.freedesktop.org (Postfix) with ESMTPS id 19C136EC27 for ; Thu, 22 Mar 2018 14:00:59 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga103.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 22 Mar 2018 07:00:58 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.48,345,1517904000"; d="scan'208";a="30323568" Received: from intel-desktop.iind.intel.com ([10.223.26.163]) by fmsmga002.fm.intel.com with ESMTP; 22 Mar 2018 07:00:56 -0700 From: Praveen Paneri To: intel-gfx@lists.freedesktop.org Date: Thu, 22 Mar 2018 19:44:58 +0530 Message-Id: <1521728098-3669-6-git-send-email-praveen.paneri@intel.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1521728098-3669-1-git-send-email-praveen.paneri@intel.com> References: <1521728098-3669-1-git-send-email-praveen.paneri@intel.com> Subject: [Intel-gfx] [RFC 5/5] drm/i915: Update process mm stats for Gen GFX memory X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: daniel.vetter@ffwll.ch, nidhi1.gupta@intel.com MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP From: Sourab Gupta The GFX memory consumed by a process is not accounted by kernel. This leads to a scenario wherein the low memory killer is not able to correctly identify the best process to be killed during OOM scenarios. This case particularly manifests when an application has a large GFX memory footprint but has a significantly smaller system mem consumption. Low mem killer in such a case will not be able to identify this culprit process, and lot of innocent process will be killed without freeing much memory. This patch utilizes the memtracker functions to add the accounting for the processes' GFX memory consumption. The internal kernel counters updated thus don't affect the output of procrank, meminfo or smaps. The kernel counters updated though would lead to better approximation of process' memory consumption, leading to better low mem killer behavior. The memtracker functions are called at asynchronous points during shrinker invocation. Thus, in times of memory stress, we ensure to update the processes' GFX mem statistics, therefore leading to better low mem killer behavior Signed-off-by: Sourab Gupta Signed-off-by: Akash Goel Signed-off-by: Nidhi Gupta Signed-off-by: Praveen Paneri --- drivers/gpu/drm/i915/i915_drv.h | 8 ++++++ drivers/gpu/drm/i915/i915_gem.c | 47 +++++++++++++++++++++++++++----- drivers/gpu/drm/i915/i915_gem_shrinker.c | 18 ++++++++++++ drivers/gpu/drm/i915/i915_sysfs.c | 22 +++++++++++---- 4 files changed, 82 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 85a3dd9..0646175 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -316,6 +316,14 @@ struct i915_hotplug { struct i915_mm_struct; struct i915_mmu_object; +struct i915_gem_file_attr_priv { + char tgid_str[16]; + struct pid *tgid; + size_t rss_size; + struct mm_struct *mm; + struct drm_i915_error_state_buf buf; +}; + struct drm_i915_file_private { struct drm_i915_private *dev_priv; struct drm_file *file; diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 25845652..ef6dea2 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -82,6 +82,7 @@ struct pid_stat_entry { struct drm_open_hash namelist; struct per_file_obj_mem_info stats; struct pid *tgid; + struct i915_gem_file_attr_priv *attr_priv; int pid_num; }; @@ -6289,6 +6290,24 @@ static int i915_get_pid_cmdline(struct task_struct *task, char *buffer) return 0; } +static void i915_update_task_mm_stats(struct pid_stat_entry *pid_entry) +{ + long new_size, old_size; + + new_size = + (pid_entry->stats.phys_space_shared_proportion + + pid_entry->stats.phys_space_allocated_priv) / PAGE_SIZE; + + old_size = pid_entry->attr_priv->rss_size; + + /* Update task mm stats */ + if (pid_entry->attr_priv->mm) + add_mm_counter(pid_entry->attr_priv->mm, MM_FILEPAGES, + new_size - old_size); + + pid_entry->attr_priv->rss_size = new_size; +} + static int i915_gem_obj_insert_pid(struct drm_i915_gem_object *obj) { int found = 0; @@ -6810,6 +6829,7 @@ static int i915_gem_object_pid_order(int id, void *ptr, void *data) &sorted_pid_stats, head) { struct task_struct *task = get_pid_task(pid_entry->tgid, PIDTYPE_PID); + struct drm_i915_gem_client_pid *client_pid; err_printf(m, "%5d %6d %6d %6d %9d %8d %14zdK %14zdK %14zdK %14zdK %s", pid_entry->pid_num, @@ -6829,6 +6849,16 @@ static int i915_gem_object_pid_order(int id, void *ptr, void *data) else err_puts(m, "\n"); + list_for_each_entry(client_pid, + &dev_priv->mm.gem_client_pids, head) { + if (client_pid->tgid == pid_entry->pid_num) { + pid_entry->attr_priv = + client_pid->obj_attr.private; + i915_update_task_mm_stats(pid_entry); + break; + } + } + total_shared_prop_space += pid_entry->stats.phys_space_shared_proportion/1024; total_priv_space += @@ -6872,10 +6902,12 @@ static int i915_gem_object_pid_order(int id, void *ptr, void *data) __i915_gem_get_obj_info(struct drm_i915_error_state_buf *m, struct drm_device *dev, struct pid *tgid) { + struct drm_i915_private *i915 = to_i915(dev); struct drm_file *file; int bytes_copy, ret = 0; struct pid_stat_entry pid_entry; struct name_entry *entry, *next; + struct drm_i915_gem_client_pid *client_pid; pid_entry.stats.phys_space_shared_proportion = 0; pid_entry.stats.phys_space_allocated_priv = 0; @@ -6910,6 +6942,14 @@ static int i915_gem_object_pid_order(int id, void *ptr, void *data) break; } + list_for_each_entry(client_pid, &i915->mm.gem_client_pids, head) { + if (client_pid->tgid == pid_entry.pid_num) { + pid_entry.attr_priv = client_pid->obj_attr.private; + i915_update_task_mm_stats(&pid_entry); + break; + } + } + /* Reset the bytes counter to buffer beginning */ bytes_copy = m->bytes; m->bytes = 0; @@ -6947,15 +6987,8 @@ int i915_get_drm_clients_info(struct drm_i915_error_state_buf *m, * XXX: drm_global_mutex is undefined currently */ /* mutex_lock(&drm_global_mutex); */ - ret = i915_mutex_lock_interruptible(dev); - if (ret) { - /* mutex_unlock(&drm_global_mutex); */ - return ret; - } - ret = __i915_get_drm_clients_info(m, dev); - mutex_unlock(&dev->struct_mutex); /* mutex_unlock(&drm_global_mutex); */ return ret; diff --git a/drivers/gpu/drm/i915/i915_gem_shrinker.c b/drivers/gpu/drm/i915/i915_gem_shrinker.c index 5757fb7..09fe3bf 100644 --- a/drivers/gpu/drm/i915/i915_gem_shrinker.c +++ b/drivers/gpu/drm/i915/i915_gem_shrinker.c @@ -304,6 +304,22 @@ unsigned long i915_gem_shrink_all(struct drm_i915_private *i915) return freed; } +static void i915_gem_update_gfx_stats(struct drm_device *dev) +{ + struct drm_i915_private *i915 = to_i915(dev); + struct drm_i915_error_state_buf error_str; + bool unlock; + + if (!shrinker_lock(i915, &unlock)) + return; + + error_str.bytes = 0; + error_str.size = 0; + error_str.err = -ENOSPC; + i915_get_drm_clients_info(&error_str, dev); + shrinker_unlock(i915, unlock); +} + static unsigned long i915_gem_shrinker_count(struct shrinker *shrinker, struct shrink_control *sc) { @@ -341,6 +357,8 @@ unsigned long i915_gem_shrink_all(struct drm_i915_private *i915) 128ul /* default SHRINK_BATCH */); } + i915_gem_update_gfx_stats(&i915->drm); + return count; } diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c index 7f7d74a..5829aec 100644 --- a/drivers/gpu/drm/i915/i915_sysfs.c +++ b/drivers/gpu/drm/i915/i915_sysfs.c @@ -29,6 +29,7 @@ #include #include #include +#include #include "intel_drv.h" #include "i915_drv.h" @@ -570,7 +571,13 @@ static ssize_t i915_gem_clients_state_read(struct file *filp, if (ret) return ret; + ret = i915_mutex_lock_interruptible(dev); + if (ret) + goto out; + ret = i915_get_drm_clients_info(&error_str, dev); + + mutex_unlock(&dev->struct_mutex); if (ret) goto out; @@ -585,12 +592,6 @@ static ssize_t i915_gem_clients_state_read(struct file *filp, #define GEM_OBJ_STAT_BUF_SIZE (4*1024) /* 4KB */ #define GEM_OBJ_STAT_BUF_SIZE_MAX (1024*1024) /* 1MB */ -struct i915_gem_file_attr_priv { - char tgid_str[16]; - struct pid *tgid; - struct drm_i915_error_state_buf buf; -}; - static ssize_t i915_gem_read_objects(struct file *filp, struct kobject *memtrack_kobj, struct bin_attribute *attr, @@ -727,6 +728,9 @@ int i915_gem_create_sysfs_file_entry(struct drm_device *dev, obj_attr->size = 0; obj_attr->read = i915_gem_read_objects; + attr_priv->rss_size = 0; + attr_priv->mm = current->mm; + atomic_inc(¤t->mm->mm_count); attr_priv->tgid = tgid; obj_attr->private = attr_priv; @@ -761,6 +765,12 @@ void i915_gem_remove_sysfs_file_entry(struct drm_device *dev, attr_priv = obj_attr->private; + if (attr_priv->mm) { + add_mm_counter(attr_priv->mm, MM_FILEPAGES, + -attr_priv->rss_size); + mmdrop(attr_priv->mm); + } + sysfs_remove_bin_file(&dev_priv->memtrack_kobj, obj_attr); i915_error_state_buf_release(&attr_priv->buf);