All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC 0/5] drm/i915: Interface to get GFX shmem usage stats per process
@ 2018-03-22 14:14 Praveen Paneri
  2018-03-22 14:14 ` [RFC 1/5] drm/i915: Sysfs interface " Praveen Paneri
                   ` (7 more replies)
  0 siblings, 8 replies; 11+ messages in thread
From: Praveen Paneri @ 2018-03-22 14:14 UTC (permalink / raw)
  To: intel-gfx; +Cc: daniel.vetter, nidhi1.gupta

This series introduces a new gfx driver interface for tracking graphics
memory usage at per process level. This interface is currently needed by
android memtracker HAL and it can also be used with driver's shrinker
interface (see patch 5).

This feature was last floated to ML by Sourab and the discussion can be
viewed here-
https://lists.freedesktop.org/archives/intel-gfx/2014-September/051687.html
Two major comments that I could see here are
 1) Handling of cases where drm fd is shared across processes.
 2) Sysfs is probably not a right place for this. Debugfs would be more
    appropriate?

I have tried to address (1) by moving away from "per drm fd based object
accounting" to "per process based object accounting". With that, gfx
memory consumed by child process created by fork() gets accounted
separately from the parent process even though they share the same fd.

WIP on-
 - filesystem switch as mentioned in (2) above
 - some IGT failures observed with the series

I would like to get early reviews and feedback on this while I work on
above points.

Credits:
Sourab and Akash (Authors)
Nidhi (Rebased to latest drm-tip)
Praveen (Worked on review comments and other fixes)

Sourab Gupta (5):
  drm/i915: Sysfs interface to get GFX shmem usage stats per process
  drm/i915: Calculate total shmem GFX memory consumed
  drm/i915: Sysfs interface to get detailed GFX buffer info per process
  drm/i915: Output the user virtual addresses for GFX buffers
  drm/i915: Update process mm stats for Gen GFX memory

 drivers/gpu/drm/i915/i915_debugfs.c      |   15 -
 drivers/gpu/drm/i915/i915_drv.c          |    1 +
 drivers/gpu/drm/i915/i915_drv.h          |   25 +
 drivers/gpu/drm/i915/i915_gem.c          | 1009 +++++++++++++++++++++++++++++-
 drivers/gpu/drm/i915/i915_gem_object.h   |    2 +
 drivers/gpu/drm/i915/i915_gem_shrinker.c |   18 +
 drivers/gpu/drm/i915/i915_gpu_error.c    |   23 +-
 drivers/gpu/drm/i915/i915_gpu_error.h    |    6 +
 drivers/gpu/drm/i915/i915_params.c       |    2 +
 drivers/gpu/drm/i915/i915_params.h       |    3 +-
 drivers/gpu/drm/i915/i915_sysfs.c        |  272 ++++++++
 11 files changed, 1356 insertions(+), 20 deletions(-)

-- 
1.9.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [RFC 1/5] drm/i915: Sysfs interface to get GFX shmem usage stats per process
  2018-03-22 14:14 [RFC 0/5] drm/i915: Interface to get GFX shmem usage stats per process Praveen Paneri
@ 2018-03-22 14:14 ` Praveen Paneri
  2018-03-22 14:15   ` Chris Wilson
  2018-03-22 14:14 ` [RFC 2/5] drm/i915: Calculate total shmem GFX memory consumed Praveen Paneri
                   ` (6 subsequent siblings)
  7 siblings, 1 reply; 11+ messages in thread
From: Praveen Paneri @ 2018-03-22 14:14 UTC (permalink / raw)
  To: intel-gfx; +Cc: daniel.vetter, nidhi1.gupta

From: Sourab Gupta <sourab.gupta@intel.com>

There's a need for an interface which provide information about GFX
memory usage per process, at any instantaneous point of time.
Such information is useful to analyze GFX memory usage of the processes,
on the lines of other system memory usage tools (e.g. procrank).
This is especially useful for the GFX intensive processes, since the
tools such as procrank may not be able to provide a precise view of
GFX memory consumption, with its specific intricacies (such as
differentiation between private, shared and purgeable buffers).

The patch provides a sysfs interface to list GFX memory usage for
each client process. The interface also provides GFX buffers/memory
usage information categorized into various buckets according to buffer
type such as purgeable, private, shared.

v2:
  -Move from per drm file accounting to per process accounting to
   address shared drm fd cases (Daniel)
  -Use div64_u64 for 64 bit divisions (Sagar)

Signed-off-by: Sourab Gupta <sourab.gupta@intel.com>
Signed-off-by: Akash Goel <akash.goel@intel.com>
Signed-off-by: Nidhi Gupta <nidhi1.gupta@intel.com>
Signed-off-by: Praveen Paneri <praveen.paneri@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.c        |   1 +
 drivers/gpu/drm/i915/i915_drv.h        |   4 +
 drivers/gpu/drm/i915/i915_gem.c        | 548 +++++++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/i915_gem_object.h |   1 +
 drivers/gpu/drm/i915/i915_gpu_error.c  |   9 +-
 drivers/gpu/drm/i915/i915_gpu_error.h  |   4 +
 drivers/gpu/drm/i915/i915_params.c     |   2 +
 drivers/gpu/drm/i915/i915_params.h     |   3 +-
 drivers/gpu/drm/i915/i915_sysfs.c      |  78 +++++
 9 files changed, 647 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index a7d3275..06c0901 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -2847,6 +2847,7 @@ static int intel_runtime_resume(struct device *kdev)
 	.lastclose = i915_driver_lastclose,
 	.postclose = i915_driver_postclose,
 
+	.gem_open_object = i915_gem_open_object,
 	.gem_close_object = i915_gem_close_object,
 	.gem_free_object_unlocked = i915_gem_free_object,
 	.gem_vm_ops = &i915_gem_vm_ops,
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index c9c3b2b..c23ba28 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1660,6 +1660,7 @@ struct drm_i915_private {
 
 	bool preserve_bios_swizzle;
 
+	struct kobject memtrack_kobj;
 	/* overlay */
 	struct intel_overlay *overlay;
 
@@ -2884,6 +2885,7 @@ struct drm_i915_gem_object *
 struct drm_i915_gem_object *
 i915_gem_object_create_from_data(struct drm_i915_private *dev_priv,
 				 const void *data, size_t size);
+int i915_gem_open_object(struct drm_gem_object *gem, struct drm_file *file);
 void i915_gem_close_object(struct drm_gem_object *gem, struct drm_file *file);
 void i915_gem_free_object(struct drm_gem_object *obj);
 
@@ -3352,6 +3354,8 @@ int intel_engine_cmd_parser(struct intel_engine_cs *engine,
 /* i915_sysfs.c */
 void i915_setup_sysfs(struct drm_i915_private *dev_priv);
 void i915_teardown_sysfs(struct drm_i915_private *dev_priv);
+int i915_get_drm_clients_info(struct drm_i915_error_state_buf *m,
+			      struct drm_device *dev);
 
 /* intel_lpe_audio.c */
 int  intel_lpe_audio_init(struct drm_i915_private *dev_priv);
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 802df8e..49555ea 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -45,8 +45,83 @@
 #include <linux/swap.h>
 #include <linux/pci.h>
 #include <linux/dma-buf.h>
+#include <linux/sched/mm.h>
+
+/**< Size of key hash table. Must be power of 2. */
+#define DRM_DEBUG_MAGIC_HASH_ORDER  4
+
+struct per_file_obj_mem_info {
+	int num_obj;
+	int num_obj_shared;
+	int num_obj_private;
+	int num_obj_gtt_bound;
+	int num_obj_purged;
+	int num_obj_purgeable;
+	int num_obj_allocated;
+	int num_obj_fault_mappable;
+	int num_obj_stolen;
+	size_t gtt_space_allocated_shared;
+	size_t gtt_space_allocated_priv;
+	size_t phys_space_allocated_shared;
+	size_t phys_space_allocated_priv;
+	size_t phys_space_purgeable;
+	size_t phys_space_shared_proportion;
+	size_t fault_mappable_size;
+	size_t stolen_space_allocated;
+	char *process_name;
+};
+
+struct name_entry {
+	struct list_head head;
+	struct drm_hash_item hash_item;
+};
+
+struct pid_stat_entry {
+	struct list_head head;
+	struct list_head namefree;
+	struct drm_open_hash namelist;
+	struct per_file_obj_mem_info stats;
+	struct pid *tgid;
+	int pid_num;
+};
+
+struct drm_i915_obj_pid_info {
+	struct list_head head;
+	pid_t tgid;
+	int open_handle_count;
+};
+
+struct get_obj_stats_buf {
+	struct pid_stat_entry *entry;
+	struct drm_i915_error_state_buf *m;
+};
+
+#define err_printf(e, ...) i915_error_printf(e, __VA_ARGS__)
+#define err_puts(e, s) i915_error_puts(e, s)
+
+/*
+ * If this mmput call is the last one, it will tear down the mmaps of the
+ * process and calls drm_gem_vm_close(), which leads deadlock on i915 mutex.
+ * Instead, asynchronously schedule mmput function here, to avoid recursive
+ * calls to acquire i915_mutex.
+ */
+static void async_mmput_func(void *data, async_cookie_t cookie)
+{
+	struct mm_struct *mm = data;
+
+	mmput(mm);
+}
+
+static void async_mmput(struct mm_struct *mm)
+{
+	async_schedule(async_mmput_func, mm);
+}
 
 static void i915_gem_flush_free_objects(struct drm_i915_private *i915);
+static int i915_gem_obj_insert_pid(struct drm_i915_gem_object *obj);
+static int i915_get_pid_cmdline(struct task_struct *task, char *buffer);
+static void i915_gem_obj_remove_all_pids(struct drm_i915_gem_object *obj);
+static void i915_gem_obj_remove_pid(struct drm_i915_gem_object *obj);
 
 static bool cpu_write_needs_clflush(struct drm_i915_gem_object *obj)
 {
@@ -3553,6 +3628,13 @@ static void __sleep_rcu(struct rcu_head *rcu)
 	}
 }
 
+int i915_gem_open_object(struct drm_gem_object *gem, struct drm_file *file)
+{
+	struct drm_i915_gem_object *obj = to_intel_bo(gem);
+
+	return i915_gem_obj_insert_pid(obj);
+}
+
 void i915_gem_close_object(struct drm_gem_object *gem, struct drm_file *file)
 {
 	struct drm_i915_private *i915 = to_i915(gem->dev);
@@ -3588,6 +3670,9 @@ void i915_gem_close_object(struct drm_gem_object *gem, struct drm_file *file)
 	}
 
 	mutex_unlock(&i915->drm.struct_mutex);
+
+	i915_gem_obj_remove_pid(obj);
+
 }
 
 static unsigned long to_wait_timeout(s64 timeout_ns)
@@ -4582,6 +4667,7 @@ void i915_gem_object_init(struct drm_i915_gem_object *obj,
 	init_request_active(&obj->frontbuffer_write, frontbuffer_retire);
 
 	obj->mm.madv = I915_MADV_WILLNEED;
+	INIT_LIST_HEAD(&obj->pid_info);
 	INIT_RADIX_TREE(&obj->mm.get_page.radix, GFP_KERNEL | __GFP_NOWARN);
 	mutex_init(&obj->mm.get_page.lock);
 
@@ -4760,6 +4846,8 @@ static void __i915_gem_free_objects(struct drm_i915_private *i915,
 		GEM_BUG_ON(atomic_read(&obj->frontbuffer_bits));
 		GEM_BUG_ON(!list_empty(&obj->lut_list));
 
+		i915_gem_obj_remove_all_pids(obj);
+
 		if (obj->ops->release)
 			obj->ops->release(obj);
 
@@ -6004,3 +6092,463 @@ int i915_gem_object_attach_phys(struct drm_i915_gem_object *obj, int align)
 #include "selftests/i915_gem_object.c"
 #include "selftests/i915_gem_coherency.c"
 #endif
+
+static int i915_get_pid_cmdline(struct task_struct *task, char *buffer)
+{
+	int res = 0;
+	unsigned int len;
+	struct mm_struct *mm = get_task_mm(task);
+
+	if (!mm)
+		goto out;
+	if (!mm->arg_end)
+		goto out_mm;
+
+	len = mm->arg_end - mm->arg_start;
+
+	if (len > PAGE_SIZE)
+		len = PAGE_SIZE;
+
+	res = access_process_vm(task, mm->arg_start, buffer, len, 0);
+	if (res < 0) {
+		async_mmput(mm);
+		return res;
+	}
+
+	if (res > 0 && buffer[res-1] != '\0' && len < PAGE_SIZE)
+		buffer[res-1] = '\0';
+out_mm:
+	async_mmput(mm);
+out:
+	return 0;
+}
+
+static unsigned long
+i915_obj_get_shmem_pages_alloced(struct drm_i915_gem_object *obj)
+{
+	unsigned long ret;
+
+	if (obj->base.filp) {
+		struct inode *inode = file_inode(obj->base.filp);
+		struct shmem_inode_info *info = SHMEM_I(inode);
+
+		if (!inode)
+			return 0;
+		spin_lock(&info->lock);
+		ret = inode->i_mapping->nrpages;
+		spin_unlock(&info->lock);
+		return ret;
+	}
+	return 0;
+}
+
+static int i915_gem_obj_insert_pid(struct drm_i915_gem_object *obj)
+{
+	int found = 0;
+	struct drm_i915_obj_pid_info *entry;
+	pid_t current_tgid = task_tgid_nr(current);
+
+	if (!i915_modparams.memtrack_debug)
+		return 0;
+
+	mutex_lock(&obj->base.dev->struct_mutex);
+
+	list_for_each_entry(entry, &obj->pid_info, head) {
+		if (entry->tgid == current_tgid) {
+			entry->open_handle_count++;
+			found = 1;
+			break;
+		}
+	}
+	if (found == 0) {
+		entry = kzalloc(sizeof(*entry), GFP_KERNEL);
+		if (entry == NULL) {
+			DRM_ERROR("alloc failed\n");
+			mutex_unlock(&obj->base.dev->struct_mutex);
+			return -ENOMEM;
+		}
+		entry->tgid = current_tgid;
+		entry->open_handle_count = 1;
+		list_add_tail(&entry->head, &obj->pid_info);
+	}
+
+	mutex_unlock(&obj->base.dev->struct_mutex);
+	return 0;
+}
+
+static void i915_gem_obj_remove_pid(struct drm_i915_gem_object *obj)
+{
+	pid_t current_tgid = task_tgid_nr(current);
+	struct drm_i915_obj_pid_info *pid_entry, *pid_next;
+	int found = 0;
+
+	if (!i915_modparams.memtrack_debug)
+		return;
+
+	mutex_lock(&obj->base.dev->struct_mutex);
+
+	list_for_each_entry_safe(pid_entry, pid_next, &obj->pid_info, head) {
+		if (pid_entry->tgid == current_tgid) {
+			pid_entry->open_handle_count--;
+			found = 1;
+			if (pid_entry->open_handle_count == 0) {
+				list_del(&pid_entry->head);
+				kfree(pid_entry);
+			}
+			break;
+		}
+	}
+	mutex_unlock(&obj->base.dev->struct_mutex);
+
+	if (found == 0)
+		DRM_DEBUG("Couldn't find matching tgid %d for obj %p\n",
+				current_tgid, obj);
+}
+
+static void i915_gem_obj_remove_all_pids(struct drm_i915_gem_object *obj)
+{
+	struct drm_i915_obj_pid_info *pid_entry, *pid_next;
+
+	list_for_each_entry_safe(pid_entry, pid_next, &obj->pid_info, head) {
+		list_del(&pid_entry->head);
+		kfree(pid_entry);
+	}
+}
+
+static int i915_obj_find_insert_in_hash(struct drm_i915_gem_object *obj,
+				struct pid_stat_entry *pid_entry,
+				bool *found)
+{
+	struct drm_hash_item *hash_item;
+	int ret;
+
+	ret = drm_ht_find_item(&pid_entry->namelist,
+				(unsigned long)&obj->base, &hash_item);
+	/* Not found, insert in hash */
+	if (ret) {
+		struct name_entry *entry =
+			kzalloc(sizeof(*entry), GFP_NOWAIT);
+		if (entry == NULL) {
+			DRM_ERROR("alloc failed\n");
+			return -ENOMEM;
+		}
+		entry->hash_item.key = (unsigned long)&obj->base;
+		drm_ht_insert_item(&pid_entry->namelist,
+				   &entry->hash_item);
+		list_add_tail(&entry->head, &pid_entry->namefree);
+		*found = false;
+	} else
+		*found = true;
+
+	return 0;
+}
+
+static int i915_obj_shared_count(struct drm_i915_gem_object *obj,
+				struct pid_stat_entry *pid_entry,
+				bool *discard)
+{
+	struct drm_i915_obj_pid_info *pid_info_entry;
+	int ret, obj_shared_count = 0;
+
+	/*
+	 * The object can be shared among different processes by either flink
+	 * or dma-buf mechanism, leading to shared count more than 1. For the
+	 * objects not shared , return the shared count as 1.
+	 * In case of shared dma-buf objects, there's a possibility that these
+	 * may be external to i915. Detect this condition through
+	 * 'import_attach' field.
+	 */
+	if (!obj->base.name && !obj->base.dma_buf)
+		return 1;
+	else if (obj->base.import_attach) {
+		/* not our GEM obj */
+		*discard = true;
+		return 0;
+	}
+
+	ret = i915_obj_find_insert_in_hash(obj, pid_entry, discard);
+	if (ret)
+		return ret;
+
+	list_for_each_entry(pid_info_entry, &obj->pid_info, head)
+		obj_shared_count++;
+
+	if (WARN_ON(obj_shared_count == 0))
+		return -EINVAL;
+
+	return obj_shared_count;
+}
+
+static int
+i915_drm_gem_obj_per_process_summary(struct drm_i915_gem_object *obj,
+				     struct pid_stat_entry *pid_entry)
+{
+	struct per_file_obj_mem_info *stats = &pid_entry->stats;
+	int obj_shared_count = 0;
+	bool discard = false;
+
+	stats->num_obj++;
+
+	obj_shared_count = i915_obj_shared_count(obj, pid_entry, &discard);
+	if (obj_shared_count < 0)
+		return obj_shared_count;
+
+	if (discard)
+		return 0;
+
+	if (obj_shared_count > 1)
+		stats->num_obj_shared++;
+	else
+		stats->num_obj_private++;
+
+	if (obj->bind_count) {
+		stats->num_obj_gtt_bound++;
+		if (obj_shared_count > 1)
+			stats->gtt_space_allocated_shared += obj->base.size;
+		else
+			stats->gtt_space_allocated_priv += obj->base.size;
+	}
+
+	if (obj->stolen) {
+		stats->num_obj_stolen++;
+		stats->stolen_space_allocated += obj->base.size;
+	} else if (obj->mm.madv == __I915_MADV_PURGED) {
+		stats->num_obj_purged++;
+	} else {
+		u64 nr_bytes =
+			i915_obj_get_shmem_pages_alloced(obj)*PAGE_SIZE;
+
+		if (obj->mm.madv == I915_MADV_DONTNEED) {
+			stats->num_obj_purgeable++;
+			if (nr_bytes != 0)
+				stats->phys_space_purgeable += nr_bytes;
+		}
+
+		if (nr_bytes != 0) {
+			stats->num_obj_allocated++;
+			if (obj_shared_count > 1) {
+				stats->phys_space_allocated_shared += nr_bytes;
+				stats->phys_space_shared_proportion +=
+					div64_u64(nr_bytes, obj_shared_count);
+			} else
+				stats->phys_space_allocated_priv += nr_bytes;
+		}
+	}
+
+	if (!list_empty(&obj->userfault_link)) {
+		stats->num_obj_fault_mappable++;
+		stats->fault_mappable_size += obj->base.size;
+	}
+
+	return 0;
+}
+
+static int i915_gem_object_pid_order(int id, void *ptr, void *data)
+{
+	struct drm_i915_gem_object *obj = ptr;
+	struct list_head *per_pid_stats = data;
+	struct pid_stat_entry *pid_entry;
+	struct drm_i915_obj_pid_info *pid_info;
+	int ret = 0;
+
+	list_for_each_entry(pid_info, &obj->pid_info, head) {
+		int pid_num = pid_info->tgid;
+		int found = 0;
+
+		list_for_each_entry(pid_entry, per_pid_stats, head) {
+			if (pid_entry->pid_num == pid_num) {
+				found = 1;
+				break;
+			}
+		}
+
+		if (!found) {
+			char *process_name;
+			struct task_struct *task;
+			struct pid_stat_entry *new_entry =
+				kzalloc(sizeof(*new_entry), GFP_KERNEL);
+			if (new_entry == NULL) {
+				DRM_ERROR("alloc failed\n");
+				ret = -ENOMEM;
+				break;
+			}
+
+			new_entry->pid_num = pid_num;
+			new_entry->tgid = find_get_pid(pid_num);
+
+			ret = drm_ht_create(&new_entry->namelist,
+					DRM_DEBUG_MAGIC_HASH_ORDER);
+			if (ret) {
+				kfree(new_entry);
+				break;
+			}
+
+			list_add_tail(&new_entry->head, per_pid_stats);
+			INIT_LIST_HEAD(&new_entry->namefree);
+
+			process_name = kzalloc(PAGE_SIZE, GFP_ATOMIC);
+			if (!process_name) {
+				kfree(new_entry);
+				ret = -ENOMEM;
+				break;
+			}
+
+			task = get_pid_task(new_entry->tgid, PIDTYPE_PID);
+			ret = i915_get_pid_cmdline(task, process_name);
+			if (ret) {
+				kfree(new_entry);
+				kfree(process_name);
+				break;
+			}
+			new_entry->stats.process_name = process_name;
+			pid_entry = new_entry;
+		}
+		/* Add this entry into per process accounting now */
+		i915_drm_gem_obj_per_process_summary(obj, pid_entry);
+
+	}
+
+	return ret;
+}
+
+static int
+__i915_get_drm_clients_info(struct drm_i915_error_state_buf *m,
+			    struct drm_device *dev)
+{
+	struct drm_file *file;
+
+	struct name_entry *entry, *next;
+	struct pid_stat_entry *pid_entry, *temp_entry;
+	struct pid_stat_entry *new_pid_entry, *new_temp_entry;
+	struct list_head per_pid_stats, sorted_pid_stats;
+	int ret = 0;
+	size_t total_shared_prop_space = 0, total_priv_space = 0;
+
+	INIT_LIST_HEAD(&per_pid_stats);
+	INIT_LIST_HEAD(&sorted_pid_stats);
+
+	err_puts(m,
+		"\n\n  pid   Total  Shared  Priv   Purgeable  Alloced  SharedPHYsize   SharedPHYprop    PrivPHYsize   PurgeablePHYsize   process\n");
+
+	list_for_each_entry(file, &dev->filelist, lhead) {
+		spin_lock(&file->table_lock);
+		ret = idr_for_each(&file->object_idr,
+				   &i915_gem_object_pid_order,
+				   &per_pid_stats);
+		spin_unlock(&file->table_lock);
+		if (ret)
+			break;
+	}
+
+	list_for_each_entry_safe(pid_entry, temp_entry, &per_pid_stats, head) {
+		if (list_empty(&sorted_pid_stats)) {
+			list_del(&pid_entry->head);
+			list_add_tail(&pid_entry->head, &sorted_pid_stats);
+			continue;
+		}
+
+		list_for_each_entry_safe(new_pid_entry, new_temp_entry,
+			&sorted_pid_stats, head) {
+			int prev_space =
+				pid_entry->stats.phys_space_shared_proportion +
+				pid_entry->stats.phys_space_allocated_priv;
+			int new_space =
+				new_pid_entry->
+				stats.phys_space_shared_proportion +
+				new_pid_entry->stats.phys_space_allocated_priv;
+			if (prev_space > new_space) {
+				list_del(&pid_entry->head);
+				list_add_tail(&pid_entry->head,
+					&new_pid_entry->head);
+				break;
+			}
+			if (list_is_last(&new_pid_entry->head,
+				&sorted_pid_stats)) {
+				list_del(&pid_entry->head);
+				list_add_tail(&pid_entry->head,
+						&sorted_pid_stats);
+			}
+		}
+	}
+
+	list_for_each_entry_safe(pid_entry, temp_entry,
+				&sorted_pid_stats, head) {
+		struct task_struct *task = get_pid_task(pid_entry->tgid,
+							PIDTYPE_PID);
+		err_printf(m,
+			"%5d %6d %6d %6d %9d %8d %14zdK %14zdK %14zdK  %14zdK     %s",
+			   pid_entry->pid_num,
+			   pid_entry->stats.num_obj,
+			   pid_entry->stats.num_obj_shared,
+			   pid_entry->stats.num_obj_private,
+			   pid_entry->stats.num_obj_purgeable,
+			   pid_entry->stats.num_obj_allocated,
+			   pid_entry->stats.phys_space_allocated_shared/1024,
+			   pid_entry->stats.phys_space_shared_proportion/1024,
+			   pid_entry->stats.phys_space_allocated_priv/1024,
+			   pid_entry->stats.phys_space_purgeable/1024,
+			   pid_entry->stats.process_name);
+
+		if (task == NULL)
+			err_puts(m, "*\n");
+		else
+			err_puts(m, "\n");
+
+		total_shared_prop_space +=
+			pid_entry->stats.phys_space_shared_proportion/1024;
+		total_priv_space +=
+			pid_entry->stats.phys_space_allocated_priv/1024;
+		list_del(&pid_entry->head);
+
+		list_for_each_entry_safe(entry, next,
+					&pid_entry->namefree, head) {
+			list_del(&entry->head);
+			drm_ht_remove_item(&pid_entry->namelist,
+					&entry->hash_item);
+			kfree(entry);
+		}
+		drm_ht_remove(&pid_entry->namelist);
+		kfree(pid_entry->stats.process_name);
+		kfree(pid_entry);
+		if (task)
+			put_task_struct(task);
+	}
+
+	err_puts(m,
+		"\t\t\t\t\t\t\t\t--------------\t-------------\t--------\n");
+	err_printf(m,
+		"\t\t\t\t\t\t\t\t%13zdK\t%12zdK\tTotal\n",
+			total_shared_prop_space, total_priv_space);
+
+	if (ret)
+		return ret;
+	if (m->bytes == 0 && m->err)
+		return m->err;
+
+	return 0;
+}
+
+int i915_get_drm_clients_info(struct drm_i915_error_state_buf *m,
+			      struct drm_device *dev)
+{
+	int ret = 0;
+
+	/*
+	 * Protect the access to global drm resources such as filelist. Protect
+	 * against their removal under our noses, while in use.
+	 * 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_object.h b/drivers/gpu/drm/i915/i915_gem_object.h
index 54f00b3..8176d7d 100644
--- a/drivers/gpu/drm/i915/i915_gem_object.h
+++ b/drivers/gpu/drm/i915/i915_gem_object.h
@@ -279,6 +279,7 @@ struct drm_i915_gem_object {
 
 		void *gvt_info;
 	};
+	struct list_head pid_info;
 
 	/** for phys allocated objects */
 	struct drm_dma_handle *phys_handle;
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c
index effaf98..3e8fc79 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.c
+++ b/drivers/gpu/drm/i915/i915_gpu_error.c
@@ -90,6 +90,11 @@ static bool __i915_error_ok(struct drm_i915_error_state_buf *e)
 	return true;
 }
 
+bool i915_error_ok(struct drm_i915_error_state_buf *e)
+{
+	return __i915_error_ok(e);
+}
+
 static bool __i915_error_seek(struct drm_i915_error_state_buf *e,
 			      unsigned len)
 {
@@ -161,8 +166,8 @@ static void i915_error_vprintf(struct drm_i915_error_state_buf *e,
 	__i915_error_advance(e, len);
 }
 
-static void i915_error_puts(struct drm_i915_error_state_buf *e,
-			    const char *str)
+void i915_error_puts(struct drm_i915_error_state_buf *e,
+		     const char *str)
 {
 	unsigned len;
 
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.h b/drivers/gpu/drm/i915/i915_gpu_error.h
index ac57606..dac2a35 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.h
+++ b/drivers/gpu/drm/i915/i915_gpu_error.h
@@ -308,6 +308,10 @@ int i915_error_state_buf_init(struct drm_i915_error_state_buf *eb,
 			      struct drm_i915_private *i915,
 			      size_t count, loff_t pos);
 
+void i915_error_puts(struct drm_i915_error_state_buf *e,
+		     const char *str);
+bool i915_error_ok(struct drm_i915_error_state_buf *e);
+
 static inline void
 i915_error_state_buf_release(struct drm_i915_error_state_buf *eb)
 {
diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c
index 08108ce..746d45c 100644
--- a/drivers/gpu/drm/i915/i915_params.c
+++ b/drivers/gpu/drm/i915/i915_params.c
@@ -178,6 +178,8 @@ struct i915_params i915_modparams __read_mostly = {
 i915_param_named(enable_gvt, bool, 0400,
 	"Enable support for Intel GVT-g graphics virtualization host support(default:false)");
 
+i915_param_named(memtrack_debug, bool, 0600, "use memtrack capability (default:true)");
+
 static __always_inline void _print_param(struct drm_printer *p,
 					 const char *name,
 					 const char *type,
diff --git a/drivers/gpu/drm/i915/i915_params.h b/drivers/gpu/drm/i915/i915_params.h
index c963603..40cd3ab 100644
--- a/drivers/gpu/drm/i915/i915_params.h
+++ b/drivers/gpu/drm/i915/i915_params.h
@@ -69,7 +69,8 @@
 	param(bool, nuclear_pageflip, false) \
 	param(bool, enable_dp_mst, true) \
 	param(bool, enable_dpcd_backlight, false) \
-	param(bool, enable_gvt, false)
+	param(bool, enable_gvt, false) \
+	param(bool, memtrack_debug, true)
 
 #define MEMBER(T, member, ...) T member;
 struct i915_params {
diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c
index e5e6f6b..d35c789 100644
--- a/drivers/gpu/drm/i915/i915_sysfs.c
+++ b/drivers/gpu/drm/i915/i915_sysfs.c
@@ -552,6 +552,36 @@ static ssize_t error_state_write(struct file *file, struct kobject *kobj,
 
 	return count;
 }
+static ssize_t i915_gem_clients_state_read(struct file *filp,
+				struct kobject *memtrack_kobj,
+				struct bin_attribute *attr,
+				char *buf, loff_t off, size_t count)
+{
+	struct kobject *kobj = memtrack_kobj->parent;
+	struct device *kdev = container_of(kobj, struct device, kobj);
+	struct drm_minor *minor = dev_get_drvdata(kdev);
+	struct drm_device *dev = minor->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_i915_error_state_buf error_str;
+	ssize_t ret_count = 0;
+	int ret;
+
+	ret = i915_error_state_buf_init(&error_str, dev_priv, count, off);
+	if (ret)
+		return ret;
+
+	ret = i915_get_drm_clients_info(&error_str, dev);
+	if (ret)
+		goto out;
+
+	ret_count = count < error_str.bytes ? count : error_str.bytes;
+
+	memcpy(buf, error_str.buf, ret_count);
+out:
+	i915_error_state_buf_release(&error_str);
+
+	return ret ?: ret_count;
+}
 
 static const struct bin_attribute error_state_attr = {
 	.attr.name = "error",
@@ -560,11 +590,51 @@ static ssize_t error_state_write(struct file *file, struct kobject *kobj,
 	.read = error_state_read,
 	.write = error_state_write,
 };
+static struct bin_attribute i915_gem_client_state_attr = {
+	.attr.name = "i915_gem_meminfo",
+	.attr.mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH,
+	.size = 0,
+	.read = i915_gem_clients_state_read,
+};
+
+static struct attribute *memtrack_kobj_attrs[] = {NULL};
+
+static struct kobj_type memtrack_kobj_type = {
+	.release = NULL,
+	.sysfs_ops = NULL,
+	.default_attrs = memtrack_kobj_attrs,
+};
 
 static void i915_setup_error_capture(struct device *kdev)
 {
+	int ret;
+
 	if (sysfs_create_bin_file(&kdev->kobj, &error_state_attr))
 		DRM_ERROR("error_state sysfs setup failed\n");
+
+	if (i915_modparams.memtrack_debug) {
+		struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev);
+
+		/*
+		 * Create the gfx_memtrack directory for memtrack sysfs files
+		 */
+		ret = kobject_init_and_add(
+			&dev_priv->memtrack_kobj, &memtrack_kobj_type,
+			&kdev->kobj, "gfx_memtrack");
+		if (unlikely(ret != 0)) {
+			DRM_ERROR(
+				"i915 sysfs setup memtrack directory failed\n"
+				);
+			kobject_put(&dev_priv->memtrack_kobj);
+		} else {
+			ret = sysfs_create_bin_file(&dev_priv->memtrack_kobj,
+					    &i915_gem_client_state_attr);
+			if (ret)
+				DRM_ERROR(
+					  "i915_gem_client_state sysfs setup failed\n"
+				);
+		}
+	}
 }
 
 static void i915_teardown_error_capture(struct device *kdev)
@@ -641,4 +711,12 @@ void i915_teardown_sysfs(struct drm_i915_private *dev_priv)
 	sysfs_unmerge_group(&kdev->kobj, &rc6_attr_group);
 	sysfs_unmerge_group(&kdev->kobj, &rc6p_attr_group);
 #endif
+	if (i915_modparams.memtrack_debug) {
+		struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev);
+
+		sysfs_remove_bin_file(&dev_priv->memtrack_kobj,
+					&i915_gem_client_state_attr);
+		kobject_del(&dev_priv->memtrack_kobj);
+		kobject_put(&dev_priv->memtrack_kobj);
+	}
 }
-- 
1.9.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [RFC 2/5] drm/i915: Calculate total shmem GFX memory consumed
  2018-03-22 14:14 [RFC 0/5] drm/i915: Interface to get GFX shmem usage stats per process Praveen Paneri
  2018-03-22 14:14 ` [RFC 1/5] drm/i915: Sysfs interface " Praveen Paneri
@ 2018-03-22 14:14 ` Praveen Paneri
  2018-03-22 14:14 ` [RFC 3/5] drm/i915: Sysfs interface to get detailed GFX buffer info per process Praveen Paneri
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Praveen Paneri @ 2018-03-22 14:14 UTC (permalink / raw)
  To: intel-gfx; +Cc: daniel.vetter, nidhi1.gupta

From: Sourab Gupta <sourab.gupta@intel.com>

There are some GFX buffers e.g. ringbuffers, ctx buffers, etc. which
are not associated with any drm fd. Thus, the sum of the shmem memory
consumed by processes would be less than the total memory actually
consumed in the system.

This patch keeps track of all shmem memory consumptions in the system
which is given out by the sysfs interface introduced earlier.

Signed-off-by: Sourab Gupta <sourab.gupta@intel.com>
Signed-off-by: Akash Goel <akash.goel@intel.com>
Signed-off-by: Nidhi Gupta <nidhi1.gupta@intel.com>
Signed-off-by: Praveen Paneri <praveen.paneri@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h        |  2 ++
 drivers/gpu/drm/i915/i915_gem.c        | 38 +++++++++++++++++++++++++++++++---
 drivers/gpu/drm/i915/i915_gem_object.h |  1 +
 3 files changed, 38 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index c23ba28..b760133 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -980,6 +980,8 @@ struct i915_gem_mm {
 	spinlock_t object_stat_lock;
 	u64 object_memory;
 	u32 object_count;
+
+	size_t phys_mem_total;
 };
 
 #define I915_IDLE_ENGINES_TIMEOUT (200) /* in ms */
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 49555ea..6116e37 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2313,6 +2313,17 @@ static void i915_gem_object_free_mmap_offset(struct drm_i915_gem_object *obj)
 	 */
 	shmem_truncate_range(file_inode(obj->base.filp), 0, (loff_t)-1);
 	obj->mm.madv = __I915_MADV_PURGED;
+
+	/*
+	 * Mark the object as not having backing pages, as physical space
+	 * returned back to kernel
+	 */
+	if (obj->has_backing_pages == 1) {
+		struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
+
+		dev_priv->mm.phys_mem_total -= obj->base.size;
+		obj->has_backing_pages = 0;
+	}
 	obj->mm.pages = ERR_PTR(-EFAULT);
 }
 
@@ -2600,6 +2611,13 @@ static int i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj)
 
 	__i915_gem_object_set_pages(obj, st, sg_page_sizes);
 
+	if (obj->has_backing_pages == 0) {
+		struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
+
+		dev_priv->mm.phys_mem_total += obj->base.size;
+		obj->has_backing_pages = 1;
+	}
+
 	return 0;
 
 err_sg:
@@ -4667,6 +4685,11 @@ void i915_gem_object_init(struct drm_i915_gem_object *obj,
 	init_request_active(&obj->frontbuffer_write, frontbuffer_retire);
 
 	obj->mm.madv = I915_MADV_WILLNEED;
+	/*
+	 * Mark the object as not having backing pages, as no allocation
+	 * for it yet
+	 */
+	obj->has_backing_pages = 0;
 	INIT_LIST_HEAD(&obj->pid_info);
 	INIT_RADIX_TREE(&obj->mm.get_page.radix, GFP_KERNEL | __GFP_NOWARN);
 	mutex_init(&obj->mm.get_page.lock);
@@ -4858,6 +4881,13 @@ static void __i915_gem_free_objects(struct drm_i915_private *i915,
 
 		if (obj->base.import_attach)
 			drm_prime_gem_destroy(&obj->base, NULL);
+		if (!obj->stolen && (obj->has_backing_pages == 1)) {
+			struct drm_i915_private *dev_priv =
+					obj->base.dev->dev_private;
+
+			dev_priv->mm.phys_mem_total -= obj->base.size;
+			obj->has_backing_pages = 0;
+		}
 
 		reservation_object_fini(&obj->__builtin_resv);
 		drm_gem_object_release(&obj->base);
@@ -6318,6 +6348,8 @@ static int i915_obj_shared_count(struct drm_i915_gem_object *obj,
 		u64 nr_bytes =
 			i915_obj_get_shmem_pages_alloced(obj)*PAGE_SIZE;
 
+		if (obj->has_backing_pages)
+			stats->num_obj_allocated++;
 		if (obj->mm.madv == I915_MADV_DONTNEED) {
 			stats->num_obj_purgeable++;
 			if (nr_bytes != 0)
@@ -6325,7 +6357,6 @@ static int i915_obj_shared_count(struct drm_i915_gem_object *obj,
 		}
 
 		if (nr_bytes != 0) {
-			stats->num_obj_allocated++;
 			if (obj_shared_count > 1) {
 				stats->phys_space_allocated_shared += nr_bytes;
 				stats->phys_space_shared_proportion +=
@@ -6416,7 +6447,7 @@ static int i915_gem_object_pid_order(int id, void *ptr, void *data)
 			    struct drm_device *dev)
 {
 	struct drm_file *file;
-
+	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct name_entry *entry, *next;
 	struct pid_stat_entry *pid_entry, *temp_entry;
 	struct pid_stat_entry *new_pid_entry, *new_temp_entry;
@@ -6519,7 +6550,8 @@ static int i915_gem_object_pid_order(int id, void *ptr, void *data)
 	err_printf(m,
 		"\t\t\t\t\t\t\t\t%13zdK\t%12zdK\tTotal\n",
 			total_shared_prop_space, total_priv_space);
-
+	err_printf(m, "\nTotal used GFX Shmem Physical space %8zdK\n",
+		  dev_priv->mm.phys_mem_total/1024);
 	if (ret)
 		return ret;
 	if (m->bytes == 0 && m->err)
diff --git a/drivers/gpu/drm/i915/i915_gem_object.h b/drivers/gpu/drm/i915/i915_gem_object.h
index 8176d7d..8eb0288 100644
--- a/drivers/gpu/drm/i915/i915_gem_object.h
+++ b/drivers/gpu/drm/i915/i915_gem_object.h
@@ -147,6 +147,7 @@ struct drm_i915_gem_object {
 #define I915_BO_CACHE_COHERENT_FOR_READ BIT(0)
 #define I915_BO_CACHE_COHERENT_FOR_WRITE BIT(1)
 	unsigned int cache_dirty:1;
+	unsigned int has_backing_pages:1;
 
 	/**
 	 * @read_domains: Read memory domains.
-- 
1.9.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [RFC 3/5] drm/i915: Sysfs interface to get detailed GFX buffer info per process
  2018-03-22 14:14 [RFC 0/5] drm/i915: Interface to get GFX shmem usage stats per process Praveen Paneri
  2018-03-22 14:14 ` [RFC 1/5] drm/i915: Sysfs interface " Praveen Paneri
  2018-03-22 14:14 ` [RFC 2/5] drm/i915: Calculate total shmem GFX memory consumed Praveen Paneri
@ 2018-03-22 14:14 ` Praveen Paneri
  2018-03-22 14:14 ` [RFC 4/5] drm/i915: Output the user virtual addresses for GFX buffers Praveen Paneri
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Praveen Paneri @ 2018-03-22 14:14 UTC (permalink / raw)
  To: intel-gfx; +Cc: daniel.vetter, nidhi1.gupta

From: Sourab Gupta <sourab.gupta@intel.com>

Sometimes, in order to debug the mem usage scenarios, the summarized
view of GFX memory consumption per process is not sufficient, as it
doesn't provide buffer level details. Therefore, there's a need for an
interface, which can provide such detailed information.

This patch provides a sysfs interface to retrieve such detailed information
about GFX buffers used per process. Each process has a sysfs file
associated in the 'gfx_memtrack' directory, named by the process' tgid.
Reading the file will provide list of all GFX buffers open by the process,
along with their attributes such as size, pinneed, tiling, shared,
allocstate, gtt offset, etc.

v2:
 -Use div64_u64 for 64 bit divisions (Sagar)

Signed-off-by: Sourab Gupta <sourab.gupta@intel.com>
Signed-off-by: Akash Goel <akash.goel@intel.com>
Signed-off-by: Nidhi Gupta <nidhi1.gupta@intel.com>
Signed-off-by: Praveen Paneri <praveen.paneri@intel.com>
---
 drivers/gpu/drm/i915/i915_debugfs.c   |  15 --
 drivers/gpu/drm/i915/i915_drv.h       |  11 ++
 drivers/gpu/drm/i915/i915_gem.c       | 302 +++++++++++++++++++++++++++++++++-
 drivers/gpu/drm/i915/i915_gpu_error.c |  14 ++
 drivers/gpu/drm/i915/i915_gpu_error.h |   2 +
 drivers/gpu/drm/i915/i915_sysfs.c     | 184 +++++++++++++++++++++
 6 files changed, 507 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 7816cd5..94e7987 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -63,21 +63,6 @@ static char get_active_flag(struct drm_i915_gem_object *obj)
 	return i915_gem_object_is_active(obj) ? '*' : ' ';
 }
 
-static char get_pin_flag(struct drm_i915_gem_object *obj)
-{
-	return obj->pin_global ? 'p' : ' ';
-}
-
-static char get_tiling_flag(struct drm_i915_gem_object *obj)
-{
-	switch (i915_gem_object_get_tiling(obj)) {
-	default:
-	case I915_TILING_NONE: return ' ';
-	case I915_TILING_X: return 'X';
-	case I915_TILING_Y: return 'Y';
-	}
-}
-
 static char get_global_flag(struct drm_i915_gem_object *obj)
 {
 	return obj->userfault_count ? 'g' : ' ';
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index b760133..85a3dd9 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -337,6 +337,7 @@ struct drm_i915_file_private {
 	} rps_client;
 
 	unsigned int bsd_engine;
+	struct bin_attribute *obj_attr;
 
 /* Client can have a maximum of 3 contexts banned before
  * it is denied of creating new contexts. As one context
@@ -982,6 +983,8 @@ struct i915_gem_mm {
 	u32 object_count;
 
 	size_t phys_mem_total;
+	/* accounting all gem clients */
+	struct list_head gem_client_pids;
 };
 
 #define I915_IDLE_ENGINES_TIMEOUT (200) /* in ms */
@@ -2890,6 +2893,8 @@ struct drm_i915_gem_object *
 int i915_gem_open_object(struct drm_gem_object *gem, struct drm_file *file);
 void i915_gem_close_object(struct drm_gem_object *gem, struct drm_file *file);
 void i915_gem_free_object(struct drm_gem_object *obj);
+char get_pin_flag(struct drm_i915_gem_object *obj);
+char get_tiling_flag(struct drm_i915_gem_object *obj);
 
 static inline void i915_gem_drain_freed_objects(struct drm_i915_private *i915)
 {
@@ -3358,6 +3363,12 @@ int intel_engine_cmd_parser(struct intel_engine_cs *engine,
 void i915_teardown_sysfs(struct drm_i915_private *dev_priv);
 int i915_get_drm_clients_info(struct drm_i915_error_state_buf *m,
 			      struct drm_device *dev);
+int i915_gem_get_obj_info(struct drm_i915_error_state_buf *m,
+			  struct drm_device *dev, struct pid *tgid);
+int i915_gem_create_sysfs_file_entry(struct drm_device *dev,
+				     struct bin_attribute *obj_attr);
+void i915_gem_remove_sysfs_file_entry(struct drm_device *dev,
+				      struct bin_attribute *obj_attr);
 
 /* intel_lpe_audio.c */
 int  intel_lpe_audio_init(struct drm_i915_private *dev_priv);
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 6116e37..2cb6c98 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -91,6 +91,13 @@ struct drm_i915_obj_pid_info {
 	int open_handle_count;
 };
 
+struct drm_i915_gem_client_pid {
+	struct list_head head;
+	struct bin_attribute obj_attr;
+	pid_t tgid;
+	int open_obj_count;
+};
+
 struct get_obj_stats_buf {
 	struct pid_stat_entry *entry;
 	struct drm_i915_error_state_buf *m;
@@ -99,6 +106,21 @@ struct get_obj_stats_buf {
 #define err_printf(e, ...) i915_error_printf(e, __VA_ARGS__)
 #define err_puts(e, s) i915_error_puts(e, s)
 
+char get_pin_flag(struct drm_i915_gem_object *obj)
+{
+	return obj->pin_global ? 'p' : ' ';
+}
+
+char get_tiling_flag(struct drm_i915_gem_object *obj)
+{
+	switch (i915_gem_object_get_tiling(obj)) {
+	default:
+	case I915_TILING_NONE: return ' ';
+	case I915_TILING_X: return 'X';
+	case I915_TILING_Y: return 'Y';
+	}
+}
+
 /*
  * If this mmput call is the last one, it will tear down the mmaps of the
  * process and calls drm_gem_vm_close(), which leads deadlock on i915 mutex.
@@ -120,7 +142,8 @@ static void async_mmput(struct mm_struct *mm)
 static void i915_gem_flush_free_objects(struct drm_i915_private *i915);
 static int i915_gem_obj_insert_pid(struct drm_i915_gem_object *obj);
 static int i915_get_pid_cmdline(struct task_struct *task, char *buffer);
-static void i915_gem_obj_remove_all_pids(struct drm_i915_gem_object *obj);
+static void i915_gem_obj_remove_all_pids(struct drm_i915_private *i915,
+					 struct drm_i915_gem_object *obj);
 static void i915_gem_obj_remove_pid(struct drm_i915_gem_object *obj);
 
 static bool cpu_write_needs_clflush(struct drm_i915_gem_object *obj)
@@ -3646,11 +3669,85 @@ static void __sleep_rcu(struct rcu_head *rcu)
 	}
 }
 
+int i915_gem_client_add(struct drm_i915_private *i915)
+{
+	struct drm_i915_gem_client_pid *client_pid;
+	pid_t current_tgid = task_tgid_nr(current);
+	int ret, found = 0;
+
+	mutex_lock(&i915->drm.struct_mutex);
+	list_for_each_entry(client_pid, &i915->mm.gem_client_pids, head) {
+		if (client_pid->tgid == current_tgid) {
+			found = 1;
+			client_pid->open_obj_count++;
+		}
+	}
+	mutex_unlock(&i915->drm.struct_mutex);
+
+	if (!found) {
+		client_pid = kzalloc(sizeof(*client_pid), GFP_KERNEL);
+		if (client_pid == NULL) {
+			DRM_ERROR("alloc failed\n");
+			return -ENOMEM;
+		}
+		client_pid->tgid = current_tgid;
+		client_pid->open_obj_count = 1;
+		/* Create memtracker sysfs entry for this pid */
+		ret = i915_gem_create_sysfs_file_entry(&i915->drm,
+						 &client_pid->obj_attr);
+		if (ret) {
+			kfree(client_pid);
+			DRM_ERROR("Sysfs entry creation failed for pid %d",
+				  current_tgid);
+			return ret;
+		}
+
+		mutex_lock(&i915->drm.struct_mutex);
+		list_add_tail(&client_pid->head, &i915->mm.gem_client_pids);
+		mutex_unlock(&i915->drm.struct_mutex);
+
+	}
+	return 0;
+}
+
+void i915_gem_client_remove(struct drm_i915_private *i915,
+			    pid_t tgid, bool locked)
+{
+	struct drm_i915_gem_client_pid *client_pid, *next_pid, *tbr_pid = NULL;
+
+	if (!locked)
+		mutex_lock(&i915->drm.struct_mutex);
+
+	list_for_each_entry_safe(client_pid, next_pid,
+				 &i915->mm.gem_client_pids, head) {
+		if ((client_pid->tgid == tgid) &&
+		    (--client_pid->open_obj_count == 0)) {
+			list_del(&client_pid->head);
+			tbr_pid = client_pid;
+		}
+	}
+
+	if (!locked)
+		mutex_unlock(&i915->drm.struct_mutex);
+
+	if (tbr_pid) {
+		i915_gem_remove_sysfs_file_entry(&i915->drm,
+						 &tbr_pid->obj_attr);
+		kfree(tbr_pid);
+	}
+}
+
 int i915_gem_open_object(struct drm_gem_object *gem, struct drm_file *file)
 {
 	struct drm_i915_gem_object *obj = to_intel_bo(gem);
+	struct drm_i915_private *i915 = to_i915(gem->dev);
+	int ret = 0;
 
-	return i915_gem_obj_insert_pid(obj);
+	ret = i915_gem_obj_insert_pid(obj);
+	if (ret)
+		return ret;
+
+	return i915_gem_client_add(i915);
 }
 
 void i915_gem_close_object(struct drm_gem_object *gem, struct drm_file *file)
@@ -3659,6 +3756,7 @@ void i915_gem_close_object(struct drm_gem_object *gem, struct drm_file *file)
 	struct drm_i915_gem_object *obj = to_intel_bo(gem);
 	struct drm_i915_file_private *fpriv = file->driver_priv;
 	struct i915_lut_handle *lut, *ln;
+	pid_t current_tgid = task_tgid_nr(current);
 
 	mutex_lock(&i915->drm.struct_mutex);
 
@@ -3686,9 +3784,10 @@ void i915_gem_close_object(struct drm_gem_object *gem, struct drm_file *file)
 		kmem_cache_free(i915->luts, lut);
 		__i915_gem_object_release_unless_active(obj);
 	}
-
+	i915_gem_client_remove(i915, current_tgid, true);
 	mutex_unlock(&i915->drm.struct_mutex);
 
+
 	i915_gem_obj_remove_pid(obj);
 
 }
@@ -4869,7 +4968,7 @@ static void __i915_gem_free_objects(struct drm_i915_private *i915,
 		GEM_BUG_ON(atomic_read(&obj->frontbuffer_bits));
 		GEM_BUG_ON(!list_empty(&obj->lut_list));
 
-		i915_gem_obj_remove_all_pids(obj);
+		i915_gem_obj_remove_all_pids(i915, obj);
 
 		if (obj->ops->release)
 			obj->ops->release(obj);
@@ -5616,6 +5715,7 @@ static void i915_gem_init__mm(struct drm_i915_private *i915)
 	INIT_LIST_HEAD(&i915->mm.bound_list);
 	INIT_LIST_HEAD(&i915->mm.fence_list);
 	INIT_LIST_HEAD(&i915->mm.userfault_list);
+	INIT_LIST_HEAD(&i915->mm.gem_client_pids);
 
 	INIT_WORK(&i915->mm.free_work, __i915_gem_free_work);
 }
@@ -5788,7 +5888,6 @@ int i915_gem_open(struct drm_i915_private *i915, struct drm_file *file)
 	int ret;
 
 	DRM_DEBUG("\n");
-
 	file_priv = kzalloc(sizeof(*file_priv), GFP_KERNEL);
 	if (!file_priv)
 		return -ENOMEM;
@@ -6235,14 +6334,21 @@ static void i915_gem_obj_remove_pid(struct drm_i915_gem_object *obj)
 				current_tgid, obj);
 }
 
-static void i915_gem_obj_remove_all_pids(struct drm_i915_gem_object *obj)
+static void i915_gem_obj_remove_all_pids(struct drm_i915_private *i915,
+					 struct drm_i915_gem_object *obj)
 {
 	struct drm_i915_obj_pid_info *pid_entry, *pid_next;
 
+	mutex_lock(&i915->drm.struct_mutex);
 	list_for_each_entry_safe(pid_entry, pid_next, &obj->pid_info, head) {
+		/* Remove object from that pid's client list */
+		while (pid_entry->open_handle_count--)
+			i915_gem_client_remove(i915, pid_entry->tgid, true);
+
 		list_del(&pid_entry->head);
 		kfree(pid_entry);
 	}
+	mutex_unlock(&i915->drm.struct_mutex);
 }
 
 static int i915_obj_find_insert_in_hash(struct drm_i915_gem_object *obj,
@@ -6310,6 +6416,102 @@ static int i915_obj_shared_count(struct drm_i915_gem_object *obj,
 }
 
 static int
+i915_describe_obj(struct get_obj_stats_buf *obj_stat_buf,
+		  struct drm_i915_gem_object *obj)
+{
+	struct i915_vma *vma;
+	struct drm_i915_obj_pid_info *pid_info_entry;
+	struct drm_i915_error_state_buf *m = obj_stat_buf->m;
+	struct pid_stat_entry *pid_entry = obj_stat_buf->entry;
+	struct per_file_obj_mem_info *stats = &pid_entry->stats;
+	int obj_shared_count = 0;
+	bool discard = false;
+	u64 nr_bytes = 0;
+
+	obj_shared_count = i915_obj_shared_count(obj, pid_entry, &discard);
+	if (obj_shared_count < 0)
+		return obj_shared_count;
+
+	if (!obj->stolen)
+		nr_bytes = i915_obj_get_shmem_pages_alloced(obj)*PAGE_SIZE;
+
+	if (!discard && !obj->stolen &&
+			(obj->mm.madv != __I915_MADV_PURGED) &&
+			(nr_bytes != 0)) {
+		if (obj_shared_count > 1)
+			stats->phys_space_shared_proportion +=
+				div64_u64(nr_bytes, obj_shared_count);
+		else
+			stats->phys_space_allocated_priv += nr_bytes;
+	}
+
+	i915_error_printf(m,
+		"%p: %7zdK  %10zdK     %c      %c     %s      %s      %s     %s     %s",
+		   &obj->base,
+		   obj->base.size / 1024,
+		   (size_t)div64_u64(nr_bytes, 1024),
+		   get_pin_flag(obj),
+		   get_tiling_flag(obj),
+		   obj->mm.dirty ? "Y" : "N",
+		   (obj_shared_count > 1) ? "Y" : "N",
+		   (obj->userptr.mm != 0) ? "Y" : "N",
+		   obj->stolen ? "Y" : "N",
+		   (obj->pin_global || obj->userptr.mm) ? "Y" : "N");
+
+	if (obj->mm.madv == __I915_MADV_PURGED)
+		err_puts(m, "   purged    ");
+	else if (obj->mm.madv == I915_MADV_DONTNEED)
+		err_puts(m, "   purgeable ");
+	else if (obj->has_backing_pages != 0)
+		err_puts(m, "   allocated ");
+	else
+		err_puts(m, "             ");
+
+	list_for_each_entry(vma, &obj->vma_list, obj_link) {
+		if (!i915_is_ggtt(vma->vm))
+			err_puts(m, " PP    ");
+		else
+			err_puts(m, " G     ");
+		i915_error_printf(m, "  %08llx ", vma->node.start);
+	}
+	if (list_empty(&obj->vma_list))
+		err_puts(m, "                  ");
+
+	list_for_each_entry(pid_info_entry, &obj->pid_info, head)
+		i915_error_printf(m, " (%d: %d)",
+			   pid_info_entry->tgid,
+			   pid_info_entry->open_handle_count);
+
+	err_puts(m, "\n");
+
+	if (m->bytes == 0 && m->err)
+		return m->err;
+
+	return 0;
+}
+
+static int
+i915_drm_gem_obj_info(int id, void *ptr, void *data)
+{
+	struct drm_i915_gem_object *obj = ptr;
+	struct get_obj_stats_buf *obj_stat_buf = data;
+	struct drm_i915_obj_pid_info *pid_info;
+	pid_t tgid = pid_nr(obj_stat_buf->entry->tgid);
+	int ret;
+
+	list_for_each_entry(pid_info, &obj->pid_info, head) {
+
+		if (tgid != pid_info->tgid)
+			continue;
+
+		ret = i915_describe_obj(obj_stat_buf, obj);
+		if (ret)
+			return ret;
+	}
+	return ret;
+}
+
+static int
 i915_drm_gem_obj_per_process_summary(struct drm_i915_gem_object *obj,
 				     struct pid_stat_entry *pid_entry)
 {
@@ -6560,6 +6762,78 @@ static int i915_gem_object_pid_order(int id, void *ptr, void *data)
 	return 0;
 }
 
+#define NUM_SPACES 100
+#define INITIAL_SPACES_STR(x) #x
+#define SPACES_STR(x) INITIAL_SPACES_STR(x)
+
+static int
+__i915_gem_get_obj_info(struct drm_i915_error_state_buf *m,
+			struct drm_device *dev, struct pid *tgid)
+{
+	struct drm_file *file;
+	int bytes_copy, ret = 0;
+	struct pid_stat_entry pid_entry;
+	struct name_entry *entry, *next;
+
+	pid_entry.stats.phys_space_shared_proportion = 0;
+	pid_entry.stats.phys_space_allocated_priv = 0;
+	pid_entry.tgid = tgid;
+	pid_entry.pid_num = pid_nr(tgid);
+	ret = drm_ht_create(&pid_entry.namelist, DRM_DEBUG_MAGIC_HASH_ORDER);
+	if (ret)
+		return ret;
+
+	INIT_LIST_HEAD(&pid_entry.namefree);
+
+	/*
+	 * Fill up initial few bytes with spaces, to insert summary data later
+	 * on
+	 */
+	i915_error_printf(m, "%"SPACES_STR(NUM_SPACES)"s\n", " ");
+
+	err_puts(m,
+		"\n Obj Identifier   Obj-Size Resident-Size Pin Tiling Dirty Shared Vmap Stolen Mappable  AllocState Global/PP  GttOffset (PID: handle count)\n");
+
+	list_for_each_entry(file, &dev->filelist, lhead) {
+		struct get_obj_stats_buf obj_stat_buf;
+
+		obj_stat_buf.entry = &pid_entry;
+		obj_stat_buf.m = m;
+
+		spin_lock(&file->table_lock);
+		ret = idr_for_each(&file->object_idr,
+				&i915_drm_gem_obj_info, &obj_stat_buf);
+		spin_unlock(&file->table_lock);
+		if (ret)
+			break;
+	}
+
+	/* Reset the bytes counter to buffer beginning */
+	bytes_copy = m->bytes;
+	m->bytes = 0;
+
+	i915_error_printf(m, "\n  PID    GfxMem\n");
+	i915_error_printf(m, "%5d %8zdK ", pid_nr(tgid),
+			(pid_entry.stats.phys_space_shared_proportion +
+			 pid_entry.stats.phys_space_allocated_priv)/1024);
+
+	/* Reinstate the previous saved value of bytes counter */
+	m->bytes = bytes_copy;
+	list_for_each_entry_safe(entry, next, &pid_entry.namefree, head) {
+		list_del(&entry->head);
+		drm_ht_remove_item(&pid_entry.namelist,
+				&entry->hash_item);
+		kfree(entry);
+	}
+	drm_ht_remove(&pid_entry.namelist);
+
+	if (ret)
+		return ret;
+	if (m->bytes == 0 && m->err)
+		return m->err;
+	return 0;
+}
+
 int i915_get_drm_clients_info(struct drm_i915_error_state_buf *m,
 			      struct drm_device *dev)
 {
@@ -6584,3 +6858,19 @@ int i915_get_drm_clients_info(struct drm_i915_error_state_buf *m,
 
 	return ret;
 }
+
+int i915_gem_get_obj_info(struct drm_i915_error_state_buf *m,
+			struct drm_device *dev, struct pid *tgid)
+{
+	int ret = 0;
+
+	ret = i915_mutex_lock_interruptible(dev);
+	if (ret)
+		return ret;
+
+	ret = __i915_gem_get_obj_info(m, dev, tgid);
+
+	mutex_unlock(&dev->struct_mutex);
+
+	return ret;
+}
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c
index 3e8fc79..7638459 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.c
+++ b/drivers/gpu/drm/i915/i915_gpu_error.c
@@ -859,6 +859,20 @@ int i915_error_state_buf_init(struct drm_i915_error_state_buf *ebuf,
 	return 0;
 }
 
+int i915_obj_state_buf_init(struct drm_i915_error_state_buf *ebuf,
+				size_t count)
+{
+	memset(ebuf, 0, sizeof(*ebuf));
+
+	ebuf->buf = kmalloc(count, GFP_KERNEL);
+
+	if (ebuf->buf == NULL)
+		return -ENOMEM;
+
+	ebuf->size = count;
+	return 0;
+}
+
 static void i915_error_object_free(struct drm_i915_error_object *obj)
 {
 	int page;
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.h b/drivers/gpu/drm/i915/i915_gpu_error.h
index dac2a35..0db5829 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.h
+++ b/drivers/gpu/drm/i915/i915_gpu_error.h
@@ -307,6 +307,8 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *estr,
 int i915_error_state_buf_init(struct drm_i915_error_state_buf *eb,
 			      struct drm_i915_private *i915,
 			      size_t count, loff_t pos);
+int i915_obj_state_buf_init(struct drm_i915_error_state_buf *eb,
+			    size_t count);
 
 void i915_error_puts(struct drm_i915_error_state_buf *e,
 		     const char *str);
diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c
index d35c789..7f7d74a 100644
--- a/drivers/gpu/drm/i915/i915_sysfs.c
+++ b/drivers/gpu/drm/i915/i915_sysfs.c
@@ -582,6 +582,190 @@ static ssize_t i915_gem_clients_state_read(struct file *filp,
 
 	return ret ?: ret_count;
 }
+#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,
+				char *buf, loff_t off, size_t count)
+{
+	struct kobject *kobj = memtrack_kobj->parent;
+	struct device *kdev = container_of(kobj, struct device, kobj);
+	struct drm_minor *minor = dev_get_drvdata(kdev);
+	struct drm_device *dev = minor->dev;
+	struct i915_gem_file_attr_priv *attr_priv;
+	struct pid *tgid;
+	ssize_t ret_count = 0;
+	long bytes_available;
+	int ret = 0, buf_size = GEM_OBJ_STAT_BUF_SIZE;
+
+	/*
+	 * FIXME:There may arise a scenario where syfs file entry is being
+	 * removed, and may race against sysfs read. Sysfs file remove function
+	 * would have taken the drm_global_mutex and would wait for read to
+	 * finish, which is again waiting to acquire drm_global_mutex, leading
+	 * to deadlock. To avoid this, use mutex_trylock here with a timeout.
+	 *
+	 *unsigned long timeout = msecs_to_jiffies(500) + 1;
+	 *
+	 *while (!mutex_trylock(&drm_global_mutex) && --timeout)
+	 *	schedule_timeout_killable(1);
+	 *if (timeout == 0) {
+	 *	DRM_DEBUG_DRIVER("Unable to acquire drm global mutex.\n");
+	 *	return -EBUSY;
+	 *}
+	 */
+
+	if (!attr || !attr->private) {
+		ret = -EINVAL;
+		DRM_ERROR("attr | attr->private pointer is NULL\n");
+		goto out;
+	}
+
+	attr_priv = attr->private;
+	tgid = attr_priv->tgid;
+
+	if (off && !attr_priv->buf.buf) {
+		ret = -EINVAL;
+		DRM_ERROR(
+			"Buf not allocated during read with non-zero offset\n");
+		goto out;
+	}
+
+	if (off == 0) {
+retry:
+		if (!attr_priv->buf.buf) {
+			ret = i915_obj_state_buf_init(&attr_priv->buf,
+				buf_size);
+			if (ret) {
+				DRM_ERROR(
+					"obj state buf init failed. buf_size=%d\n",
+					buf_size);
+				goto out;
+			}
+		} else {
+			/* Reset the buf parameters before filling data */
+			attr_priv->buf.pos = 0;
+			attr_priv->buf.bytes = 0;
+		}
+
+		/* Read the gfx device stats */
+		ret = i915_gem_get_obj_info(&attr_priv->buf, dev, tgid);
+		if (ret)
+			goto out;
+
+		ret = i915_error_ok(&attr_priv->buf);
+		if (ret) {
+			ret = 0;
+			goto copy_data;
+		}
+		if (buf_size >= GEM_OBJ_STAT_BUF_SIZE_MAX) {
+			DRM_DEBUG_DRIVER("obj stat buf size limit reached\n");
+			ret = -ENOMEM;
+			goto out;
+		} else {
+			/* Try to reallocate buf of larger size */
+			i915_error_state_buf_release(&attr_priv->buf);
+			buf_size *= 2;
+
+			ret = i915_obj_state_buf_init(&attr_priv->buf,
+						buf_size);
+			if (ret) {
+				DRM_ERROR(
+					"obj stat buf init failed. buf_size=%d\n",
+					buf_size);
+				goto out;
+			}
+			goto retry;
+		}
+	}
+copy_data:
+
+	bytes_available = (long)attr_priv->buf.bytes - (long)off;
+
+	if (bytes_available > 0) {
+		ret_count = count < bytes_available ? count : bytes_available;
+		memcpy(buf, attr_priv->buf.buf + off, ret_count);
+	} else
+		ret_count = 0;
+
+out:
+	/* mutex_unlock(&drm_global_mutex); */
+
+	return ret ?: ret_count;
+}
+
+int i915_gem_create_sysfs_file_entry(struct drm_device *dev,
+				     struct bin_attribute *obj_attr)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct i915_gem_file_attr_priv *attr_priv;
+	struct pid *tgid = get_pid(find_vpid(task_tgid_nr(current)));
+	int ret;
+
+	if (!i915_modparams.memtrack_debug)
+		return 0;
+
+	attr_priv = kzalloc(sizeof(*attr_priv), GFP_KERNEL);
+	if (!attr_priv) {
+		DRM_ERROR("Alloc failed. Out of memory\n");
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	snprintf(attr_priv->tgid_str, 16, "%d", task_tgid_nr(current));
+	sysfs_bin_attr_init(obj_attr);
+	obj_attr->attr.name = attr_priv->tgid_str;
+	obj_attr->attr.mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
+	obj_attr->size = 0;
+	obj_attr->read = i915_gem_read_objects;
+
+	attr_priv->tgid = tgid;
+	obj_attr->private = attr_priv;
+
+	ret = sysfs_create_bin_file(&dev_priv->memtrack_kobj,
+				    obj_attr);
+	if (ret) {
+		DRM_ERROR(
+			"sysfs tgid file setup failed. tgid=%d, ret:%d\n",
+			pid_nr(tgid), ret);
+
+		goto out_attr_priv;
+	}
+	return 0;
+
+out_attr_priv:
+	kfree(attr_priv);
+out:
+	return ret;
+}
+
+void i915_gem_remove_sysfs_file_entry(struct drm_device *dev,
+				      struct bin_attribute *obj_attr)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct i915_gem_file_attr_priv *attr_priv;
+
+	if (!i915_modparams.memtrack_debug)
+		return;
+
+	if (WARN_ON(obj_attr == NULL))
+		return;
+
+	attr_priv = obj_attr->private;
+
+	sysfs_remove_bin_file(&dev_priv->memtrack_kobj, obj_attr);
+
+	i915_error_state_buf_release(&attr_priv->buf);
+	kfree(obj_attr->private);
+}
 
 static const struct bin_attribute error_state_attr = {
 	.attr.name = "error",
-- 
1.9.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [RFC 4/5] drm/i915: Output the user virtual addresses for GFX buffers
  2018-03-22 14:14 [RFC 0/5] drm/i915: Interface to get GFX shmem usage stats per process Praveen Paneri
                   ` (2 preceding siblings ...)
  2018-03-22 14:14 ` [RFC 3/5] drm/i915: Sysfs interface to get detailed GFX buffer info per process Praveen Paneri
@ 2018-03-22 14:14 ` Praveen Paneri
  2018-03-22 14:14 ` [RFC 5/5] drm/i915: Update process mm stats for Gen GFX memory Praveen Paneri
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Praveen Paneri @ 2018-03-22 14:14 UTC (permalink / raw)
  To: intel-gfx; +Cc: daniel.vetter, nidhi1.gupta

From: Sourab Gupta <sourab.gupta@intel.com>

This patch adds the functionality to output the virtual addresses
of each GFX buffer, mapped into process address space (via interfaces
such as mmap and mmap_gtt).

Signed-off-by: Sourab Gupta <sourab.gupta@intel.com>
Signed-off-by: Akash Goel <akash.goel@intel.com>
Signed-off-by: Nidhi Gupta <nidhi1.gupta@intel.com>
Signed-off-by: Praveen Paneri <praveen.paneri@intel.com>
---
 drivers/gpu/drm/i915/i915_gem.c | 112 ++++++++++++++++++++++++++++++++++++++--
 1 file changed, 107 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 2cb6c98..25845652 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -85,10 +85,16 @@ struct pid_stat_entry {
 	int pid_num;
 };
 
+struct drm_i915_obj_virt_addr {
+	struct list_head head;
+	unsigned long user_virt_addr;
+};
+
 struct drm_i915_obj_pid_info {
 	struct list_head head;
 	pid_t tgid;
 	int open_handle_count;
+	struct list_head virt_addr_head;
 };
 
 struct drm_i915_gem_client_pid {
@@ -145,6 +151,9 @@ static void async_mmput(struct mm_struct *mm)
 static void i915_gem_obj_remove_all_pids(struct drm_i915_private *i915,
 					 struct drm_i915_gem_object *obj);
 static void i915_gem_obj_remove_pid(struct drm_i915_gem_object *obj);
+static int i915_obj_insert_virt_addr(struct drm_i915_gem_object *obj,
+				     unsigned long addr, bool is_map_gtt,
+				     bool is_mutex_locked);
 
 static bool cpu_write_needs_clflush(struct drm_i915_gem_object *obj)
 {
@@ -1839,6 +1848,7 @@ static void i915_gem_object_bump_inactive_ggtt(struct drm_i915_gem_object *obj)
 	struct drm_i915_gem_mmap *args = data;
 	struct drm_i915_gem_object *obj;
 	unsigned long addr;
+	int ret;
 
 	if (args->flags & ~(I915_MMAP_WC))
 		return -EINVAL;
@@ -1884,6 +1894,10 @@ static void i915_gem_object_bump_inactive_ggtt(struct drm_i915_gem_object *obj)
 	if (IS_ERR((void *)addr))
 		return addr;
 
+	ret = i915_obj_insert_virt_addr(obj, addr, false, false);
+	if (ret)
+		return ret;
+
 	args->addr_ptr = (uint64_t) addr;
 
 	return 0;
@@ -2085,6 +2099,10 @@ int i915_gem_fault(struct vm_fault *vmf)
 		list_add(&obj->userfault_link, &dev_priv->mm.userfault_list);
 	GEM_BUG_ON(!obj->userfault_count);
 
+	ret = i915_obj_insert_virt_addr(obj,
+					(unsigned long)area->vm_start,
+					true, true);
+
 	i915_vma_set_ggtt_write(vma);
 
 err_fence:
@@ -6298,6 +6316,7 @@ static int i915_gem_obj_insert_pid(struct drm_i915_gem_object *obj)
 		}
 		entry->tgid = current_tgid;
 		entry->open_handle_count = 1;
+		INIT_LIST_HEAD(&entry->virt_addr_head);
 		list_add_tail(&entry->head, &obj->pid_info);
 	}
 
@@ -6309,6 +6328,7 @@ static void i915_gem_obj_remove_pid(struct drm_i915_gem_object *obj)
 {
 	pid_t current_tgid = task_tgid_nr(current);
 	struct drm_i915_obj_pid_info *pid_entry, *pid_next;
+	struct drm_i915_obj_virt_addr *virt_entry, *virt_next;
 	int found = 0;
 
 	if (!i915_modparams.memtrack_debug)
@@ -6321,6 +6341,13 @@ static void i915_gem_obj_remove_pid(struct drm_i915_gem_object *obj)
 			pid_entry->open_handle_count--;
 			found = 1;
 			if (pid_entry->open_handle_count == 0) {
+				list_for_each_entry_safe(virt_entry,
+						virt_next,
+						&pid_entry->virt_addr_head,
+						head) {
+					list_del(&virt_entry->head);
+					kfree(virt_entry);
+				}
 				list_del(&pid_entry->head);
 				kfree(pid_entry);
 			}
@@ -6338,9 +6365,18 @@ static void i915_gem_obj_remove_all_pids(struct drm_i915_private *i915,
 					 struct drm_i915_gem_object *obj)
 {
 	struct drm_i915_obj_pid_info *pid_entry, *pid_next;
+	struct drm_i915_obj_virt_addr *virt_entry, *virt_next;
 
 	mutex_lock(&i915->drm.struct_mutex);
 	list_for_each_entry_safe(pid_entry, pid_next, &obj->pid_info, head) {
+		list_for_each_entry_safe(virt_entry,
+					 virt_next,
+					 &pid_entry->virt_addr_head,
+					 head) {
+			list_del(&virt_entry->head);
+			kfree(virt_entry);
+		}
+
 		/* Remove object from that pid's client list */
 		while (pid_entry->open_handle_count--)
 			i915_gem_client_remove(i915, pid_entry->tgid, true);
@@ -6351,6 +6387,61 @@ static void i915_gem_obj_remove_all_pids(struct drm_i915_private *i915,
 	mutex_unlock(&i915->drm.struct_mutex);
 }
 
+static int i915_obj_insert_virt_addr(struct drm_i915_gem_object *obj,
+				     unsigned long addr,
+				     bool is_map_gtt,
+				     bool is_mutex_locked)
+{
+	struct drm_i915_obj_pid_info *pid_entry;
+	pid_t current_tgid = task_tgid_nr(current);
+	int ret = 0, found = 0;
+
+	if (!i915_modparams.memtrack_debug)
+		return 0;
+
+	if (is_map_gtt)
+		addr |= 1;
+
+	if (!is_mutex_locked) {
+		ret = i915_mutex_lock_interruptible(obj->base.dev);
+		if (ret)
+			return ret;
+	}
+
+	list_for_each_entry(pid_entry, &obj->pid_info, head) {
+		if (pid_entry->tgid == current_tgid) {
+			struct drm_i915_obj_virt_addr *virt_entry, *new_entry;
+
+			list_for_each_entry(virt_entry,
+					    &pid_entry->virt_addr_head,
+					    head) {
+				if (virt_entry->user_virt_addr == addr) {
+					found = 1;
+					break;
+				}
+			}
+			if (found)
+				break;
+			new_entry = kzalloc(sizeof(*new_entry), GFP_KERNEL);
+			if (new_entry == NULL) {
+				DRM_ERROR("alloc failed\n");
+				ret = -ENOMEM;
+				goto out;
+			}
+			new_entry->user_virt_addr = addr;
+			list_add_tail(&new_entry->head,
+				&pid_entry->virt_addr_head);
+			break;
+		}
+	}
+
+out:
+	if (!is_mutex_locked)
+		mutex_unlock(&obj->base.dev->struct_mutex);
+
+	return ret;
+}
+
 static int i915_obj_find_insert_in_hash(struct drm_i915_gem_object *obj,
 				struct pid_stat_entry *pid_entry,
 				bool *found)
@@ -6421,6 +6512,7 @@ static int i915_obj_shared_count(struct drm_i915_gem_object *obj,
 {
 	struct i915_vma *vma;
 	struct drm_i915_obj_pid_info *pid_info_entry;
+	struct drm_i915_obj_virt_addr *virt_entry;
 	struct drm_i915_error_state_buf *m = obj_stat_buf->m;
 	struct pid_stat_entry *pid_entry = obj_stat_buf->entry;
 	struct per_file_obj_mem_info *stats = &pid_entry->stats;
@@ -6475,12 +6567,22 @@ static int i915_obj_shared_count(struct drm_i915_gem_object *obj,
 		i915_error_printf(m, "  %08llx ", vma->node.start);
 	}
 	if (list_empty(&obj->vma_list))
-		err_puts(m, "                  ");
-
-	list_for_each_entry(pid_info_entry, &obj->pid_info, head)
-		i915_error_printf(m, " (%d: %d)",
+		err_puts(m, "                                    ");
+	list_for_each_entry(pid_info_entry, &obj->pid_info, head) {
+		err_printf(m, " (%d: %d:",
 			   pid_info_entry->tgid,
 			   pid_info_entry->open_handle_count);
+		list_for_each_entry(virt_entry,
+				    &pid_info_entry->virt_addr_head, head) {
+			if (virt_entry->user_virt_addr & 1)
+				err_printf(m, " %p",
+				(void *)(virt_entry->user_virt_addr & ~1));
+			else
+				err_printf(m, " %p*",
+				(void *)virt_entry->user_virt_addr);
+		}
+		err_puts(m, ") ");
+	}
 
 	err_puts(m, "\n");
 
@@ -6792,7 +6894,7 @@ static int i915_gem_object_pid_order(int id, void *ptr, void *data)
 	i915_error_printf(m, "%"SPACES_STR(NUM_SPACES)"s\n", " ");
 
 	err_puts(m,
-		"\n Obj Identifier   Obj-Size Resident-Size Pin Tiling Dirty Shared Vmap Stolen Mappable  AllocState Global/PP  GttOffset (PID: handle count)\n");
+		"\n Obj Identifier   Obj-Size Resident-Size Pin Tiling Dirty Shared Vmap Stolen Mappable  AllocState Global/PP  GttOffset (PID: handle count: user virt addrs)\n");
 
 	list_for_each_entry(file, &dev->filelist, lhead) {
 		struct get_obj_stats_buf obj_stat_buf;
-- 
1.9.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [RFC 5/5] drm/i915: Update process mm stats for Gen GFX memory
  2018-03-22 14:14 [RFC 0/5] drm/i915: Interface to get GFX shmem usage stats per process Praveen Paneri
                   ` (3 preceding siblings ...)
  2018-03-22 14:14 ` [RFC 4/5] drm/i915: Output the user virtual addresses for GFX buffers Praveen Paneri
@ 2018-03-22 14:14 ` Praveen Paneri
  2018-03-22 14:45 ` ✗ Fi.CI.CHECKPATCH: warning for drm/i915: Interface to get GFX shmem usage stats per process Patchwork
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Praveen Paneri @ 2018-03-22 14:14 UTC (permalink / raw)
  To: intel-gfx; +Cc: daniel.vetter, nidhi1.gupta

From: Sourab Gupta <sourab.gupta@intel.com>

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 <sourab.gupta@intel.com>
Signed-off-by: Akash Goel <akash.goel@intel.com>
Signed-off-by: Nidhi Gupta <nidhi1.gupta@intel.com>
Signed-off-by: Praveen Paneri <praveen.paneri@intel.com>
---
 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 <linux/module.h>
 #include <linux/stat.h>
 #include <linux/sysfs.h>
+#include <linux/sched/mm.h>
 #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(&current->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);
-- 
1.9.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [RFC 1/5] drm/i915: Sysfs interface to get GFX shmem usage stats per process
  2018-03-22 14:14 ` [RFC 1/5] drm/i915: Sysfs interface " Praveen Paneri
@ 2018-03-22 14:15   ` Chris Wilson
  0 siblings, 0 replies; 11+ messages in thread
From: Chris Wilson @ 2018-03-22 14:15 UTC (permalink / raw)
  To: Praveen Paneri, intel-gfx; +Cc: nidhi1.gupta, daniel.vetter

Quoting Praveen Paneri (2018-03-22 14:14:54)
> From: Sourab Gupta <sourab.gupta@intel.com>
> 
> There's a need for an interface which provide information about GFX
> memory usage per process, at any instantaneous point of time.

You meant per context surely. So why not solve userspace's problem in
userspace, you are missing a whole lot of rationale here to justify so
much *invasive* code.
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 11+ messages in thread

* ✗ Fi.CI.CHECKPATCH: warning for drm/i915: Interface to get GFX shmem usage stats per process
  2018-03-22 14:14 [RFC 0/5] drm/i915: Interface to get GFX shmem usage stats per process Praveen Paneri
                   ` (4 preceding siblings ...)
  2018-03-22 14:14 ` [RFC 5/5] drm/i915: Update process mm stats for Gen GFX memory Praveen Paneri
@ 2018-03-22 14:45 ` Patchwork
  2018-03-26 14:45   ` Jani Nikula
  2018-03-22 14:47 ` ✗ Fi.CI.SPARSE: " Patchwork
  2018-03-22 15:07 ` ✗ Fi.CI.BAT: failure " Patchwork
  7 siblings, 1 reply; 11+ messages in thread
From: Patchwork @ 2018-03-22 14:45 UTC (permalink / raw)
  To: Praveen Paneri; +Cc: intel-gfx

== Series Details ==

Series: drm/i915: Interface to get GFX shmem usage stats per process
URL   : https://patchwork.freedesktop.org/series/40464/
State : warning

== Summary ==

$ dim checkpatch origin/drm-tip
a2507d62bb4c drm/i915: Sysfs interface to get GFX shmem usage stats per process
-:228: CHECK:SPACING: spaces preferred around that '-' (ctx:VxV)
#228: FILE: drivers/gpu/drm/i915/i915_gem.c:6118:
+	if (res > 0 && buffer[res-1] != '\0' && len < PAGE_SIZE)
 	                         ^

-:229: CHECK:SPACING: spaces preferred around that '-' (ctx:VxV)
#229: FILE: drivers/gpu/drm/i915/i915_gem.c:6119:
+		buffer[res-1] = '\0';
 		          ^

-:275: CHECK:COMPARISON_TO_NULL: Comparison to NULL could be written "!entry"
#275: FILE: drivers/gpu/drm/i915/i915_gem.c:6165:
+		if (entry == NULL) {

-:315: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#315: FILE: drivers/gpu/drm/i915/i915_gem.c:6205:
+		DRM_DEBUG("Couldn't find matching tgid %d for obj %p\n",
+				current_tgid, obj);

-:329: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#329: FILE: drivers/gpu/drm/i915/i915_gem.c:6219:
+static int i915_obj_find_insert_in_hash(struct drm_i915_gem_object *obj,
+				struct pid_stat_entry *pid_entry,

-:336: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#336: FILE: drivers/gpu/drm/i915/i915_gem.c:6226:
+	ret = drm_ht_find_item(&pid_entry->namelist,
+				(unsigned long)&obj->base, &hash_item);

-:338: CHECK:BRACES: braces {} should be used on all arms of this statement
#338: FILE: drivers/gpu/drm/i915/i915_gem.c:6228:
+	if (ret) {
[...]
+	} else
[...]

-:341: CHECK:COMPARISON_TO_NULL: Comparison to NULL could be written "!entry"
#341: FILE: drivers/gpu/drm/i915/i915_gem.c:6231:
+		if (entry == NULL) {

-:350: CHECK:BRACES: Unbalanced braces around else statement
#350: FILE: drivers/gpu/drm/i915/i915_gem.c:6240:
+	} else

-:357: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#357: FILE: drivers/gpu/drm/i915/i915_gem.c:6247:
+static int i915_obj_shared_count(struct drm_i915_gem_object *obj,
+				struct pid_stat_entry *pid_entry,

-:371: CHECK:BRACES: braces {} should be used on all arms of this statement
#371: FILE: drivers/gpu/drm/i915/i915_gem.c:6261:
+	if (!obj->base.name && !obj->base.dma_buf)
[...]
+	else if (obj->base.import_attach) {
[...]

-:429: CHECK:SPACING: spaces preferred around that '*' (ctx:VxV)
#429: FILE: drivers/gpu/drm/i915/i915_gem.c:6319:
+			i915_obj_get_shmem_pages_alloced(obj)*PAGE_SIZE;
 			                                     ^

-:439: CHECK:BRACES: braces {} should be used on all arms of this statement
#439: FILE: drivers/gpu/drm/i915/i915_gem.c:6329:
+			if (obj_shared_count > 1) {
[...]
+			} else
[...]

-:443: CHECK:BRACES: Unbalanced braces around else statement
#443: FILE: drivers/gpu/drm/i915/i915_gem.c:6333:
+			} else

-:480: CHECK:COMPARISON_TO_NULL: Comparison to NULL could be written "!new_entry"
#480: FILE: drivers/gpu/drm/i915/i915_gem.c:6370:
+			if (new_entry == NULL) {

-:490: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#490: FILE: drivers/gpu/drm/i915/i915_gem.c:6380:
+			ret = drm_ht_create(&new_entry->namelist,
+					DRM_DEBUG_MAGIC_HASH_ORDER);

-:519: CHECK:BRACES: Blank lines aren't necessary before a close brace '}'
#519: FILE: drivers/gpu/drm/i915/i915_gem.c:6409:
+
+	}

-:541: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#541: FILE: drivers/gpu/drm/i915/i915_gem.c:6431:
+	err_puts(m,
+		"\n\n  pid   Total  Shared  Priv   Purgeable  Alloced  SharedPHYsize   SharedPHYprop    PrivPHYsize   PurgeablePHYsize   process\n");

-:561: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#561: FILE: drivers/gpu/drm/i915/i915_gem.c:6451:
+		list_for_each_entry_safe(new_pid_entry, new_temp_entry,
+			&sorted_pid_stats, head) {

-:567: WARNING:MULTILINE_DEREFERENCE: Avoid multiple line dereference - prefer 'new_pid_entry->stats.phys_space_shared_proportion'
#567: FILE: drivers/gpu/drm/i915/i915_gem.c:6457:
+				new_pid_entry->
+				stats.phys_space_shared_proportion +

-:572: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#572: FILE: drivers/gpu/drm/i915/i915_gem.c:6462:
+				list_add_tail(&pid_entry->head,
+					&new_pid_entry->head);

-:576: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#576: FILE: drivers/gpu/drm/i915/i915_gem.c:6466:
+			if (list_is_last(&new_pid_entry->head,
+				&sorted_pid_stats)) {

-:579: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#579: FILE: drivers/gpu/drm/i915/i915_gem.c:6469:
+				list_add_tail(&pid_entry->head,
+						&sorted_pid_stats);

-:585: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#585: FILE: drivers/gpu/drm/i915/i915_gem.c:6475:
+	list_for_each_entry_safe(pid_entry, temp_entry,
+				&sorted_pid_stats, head) {

-:589: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#589: FILE: drivers/gpu/drm/i915/i915_gem.c:6479:
+		err_printf(m,
+			"%5d %6d %6d %6d %9d %8d %14zdK %14zdK %14zdK  %14zdK     %s",

-:596: CHECK:SPACING: spaces preferred around that '/' (ctx:VxV)
#596: FILE: drivers/gpu/drm/i915/i915_gem.c:6486:
+			   pid_entry->stats.phys_space_allocated_shared/1024,
 			                                               ^

-:597: CHECK:SPACING: spaces preferred around that '/' (ctx:VxV)
#597: FILE: drivers/gpu/drm/i915/i915_gem.c:6487:
+			   pid_entry->stats.phys_space_shared_proportion/1024,
 			                                                ^

-:598: CHECK:SPACING: spaces preferred around that '/' (ctx:VxV)
#598: FILE: drivers/gpu/drm/i915/i915_gem.c:6488:
+			   pid_entry->stats.phys_space_allocated_priv/1024,
 			                                             ^

-:599: CHECK:SPACING: spaces preferred around that '/' (ctx:VxV)
#599: FILE: drivers/gpu/drm/i915/i915_gem.c:6489:
+			   pid_entry->stats.phys_space_purgeable/1024,
 			                                        ^

-:602: CHECK:COMPARISON_TO_NULL: Comparison to NULL could be written "!task"
#602: FILE: drivers/gpu/drm/i915/i915_gem.c:6492:
+		if (task == NULL)

-:608: CHECK:SPACING: spaces preferred around that '/' (ctx:VxV)
#608: FILE: drivers/gpu/drm/i915/i915_gem.c:6498:
+			pid_entry->stats.phys_space_shared_proportion/1024;
 			                                             ^

-:610: CHECK:SPACING: spaces preferred around that '/' (ctx:VxV)
#610: FILE: drivers/gpu/drm/i915/i915_gem.c:6500:
+			pid_entry->stats.phys_space_allocated_priv/1024;
 			                                          ^

-:614: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#614: FILE: drivers/gpu/drm/i915/i915_gem.c:6504:
+		list_for_each_entry_safe(entry, next,
+					&pid_entry->namefree, head) {

-:617: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#617: FILE: drivers/gpu/drm/i915/i915_gem.c:6507:
+			drm_ht_remove_item(&pid_entry->namelist,
+					&entry->hash_item);

-:628: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#628: FILE: drivers/gpu/drm/i915/i915_gem.c:6518:
+	err_puts(m,
+		"\t\t\t\t\t\t\t\t--------------\t-------------\t--------\n");

-:630: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#630: FILE: drivers/gpu/drm/i915/i915_gem.c:6520:
+	err_printf(m,
+		"\t\t\t\t\t\t\t\t%13zdK\t%12zdK\tTotal\n",

-:754: CHECK:LINE_SPACING: Please use a blank line after function/struct/union/enum declarations
#754: FILE: drivers/gpu/drm/i915/i915_sysfs.c:555:
 }
+static ssize_t i915_gem_clients_state_read(struct file *filp,

-:755: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#755: FILE: drivers/gpu/drm/i915/i915_sysfs.c:556:
+static ssize_t i915_gem_clients_state_read(struct file *filp,
+				struct kobject *memtrack_kobj,

-:791: CHECK:LINE_SPACING: Please use a blank line after function/struct/union/enum declarations
#791: FILE: drivers/gpu/drm/i915/i915_sysfs.c:593:
 };
+static struct bin_attribute i915_gem_client_state_attr = {

-:793: WARNING:SYMBOLIC_PERMS: Symbolic permissions 'S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH' are not preferred. Consider using octal permissions '0644'.
#793: FILE: drivers/gpu/drm/i915/i915_sysfs.c:595:
+	.attr.mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH,

-:819: CHECK:OPEN_ENDED_LINE: Lines should not end with a '('
#819: FILE: drivers/gpu/drm/i915/i915_sysfs.c:621:
+		ret = kobject_init_and_add(

-:823: CHECK:OPEN_ENDED_LINE: Lines should not end with a '('
#823: FILE: drivers/gpu/drm/i915/i915_sysfs.c:625:
+			DRM_ERROR(

-:829: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#829: FILE: drivers/gpu/drm/i915/i915_sysfs.c:631:
+			ret = sysfs_create_bin_file(&dev_priv->memtrack_kobj,
+					    &i915_gem_client_state_attr);

-:831: CHECK:OPEN_ENDED_LINE: Lines should not end with a '('
#831: FILE: drivers/gpu/drm/i915/i915_sysfs.c:633:
+				DRM_ERROR(

-:847: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#847: FILE: drivers/gpu/drm/i915/i915_sysfs.c:718:
+		sysfs_remove_bin_file(&dev_priv->memtrack_kobj,
+					&i915_gem_client_state_attr);

total: 0 errors, 2 warnings, 43 checks, 766 lines checked
27bfa55dd165 drm/i915: Calculate total shmem GFX memory consumed
-:84: CHECK:UNNECESSARY_PARENTHESES: Unnecessary parentheses around 'obj->has_backing_pages == 1'
#84: FILE: drivers/gpu/drm/i915/i915_gem.c:4884:
+		if (!obj->stolen && (obj->has_backing_pages == 1)) {

-:126: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#126: FILE: drivers/gpu/drm/i915/i915_gem.c:6554:
+	err_printf(m, "\nTotal used GFX Shmem Physical space %8zdK\n",
+		  dev_priv->mm.phys_mem_total/1024);

-:126: CHECK:SPACING: spaces preferred around that '/' (ctx:VxV)
#126: FILE: drivers/gpu/drm/i915/i915_gem.c:6554:
+		  dev_priv->mm.phys_mem_total/1024);
 		                             ^

total: 0 errors, 0 warnings, 3 checks, 101 lines checked
0d8d278defab drm/i915: Sysfs interface to get detailed GFX buffer info per process
-:167: CHECK:COMPARISON_TO_NULL: Comparison to NULL could be written "!client_pid"
#167: FILE: drivers/gpu/drm/i915/i915_gem.c:3689:
+		if (client_pid == NULL) {

-:175: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#175: FILE: drivers/gpu/drm/i915/i915_gem.c:3697:
+		ret = i915_gem_create_sysfs_file_entry(&i915->drm,
+						 &client_pid->obj_attr);

-:187: CHECK:BRACES: Blank lines aren't necessary before a close brace '}'
#187: FILE: drivers/gpu/drm/i915/i915_gem.c:3709:
+
+	}

-:201: CHECK:UNNECESSARY_PARENTHESES: Unnecessary parentheses around 'client_pid->tgid == tgid'
#201: FILE: drivers/gpu/drm/i915/i915_gem.c:3723:
+		if ((client_pid->tgid == tgid) &&
+		    (--client_pid->open_obj_count == 0)) {

-:249: CHECK:LINE_SPACING: Please don't use multiple blank lines
#249: FILE: drivers/gpu/drm/i915/i915_gem.c:3790:
 
+

-:322: CHECK:SPACING: spaces preferred around that '*' (ctx:VxV)
#322: FILE: drivers/gpu/drm/i915/i915_gem.c:6436:
+		nr_bytes = i915_obj_get_shmem_pages_alloced(obj)*PAGE_SIZE;
 		                                                ^

-:324: CHECK:UNNECESSARY_PARENTHESES: Unnecessary parentheses around 'obj->mm.madv != __I915_MADV_PURGED'
#324: FILE: drivers/gpu/drm/i915/i915_gem.c:6438:
+	if (!discard && !obj->stolen &&
+			(obj->mm.madv != __I915_MADV_PURGED) &&
+			(nr_bytes != 0)) {

-:324: CHECK:UNNECESSARY_PARENTHESES: Unnecessary parentheses around 'nr_bytes != 0'
#324: FILE: drivers/gpu/drm/i915/i915_gem.c:6438:
+	if (!discard && !obj->stolen &&
+			(obj->mm.madv != __I915_MADV_PURGED) &&
+			(nr_bytes != 0)) {

-:325: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#325: FILE: drivers/gpu/drm/i915/i915_gem.c:6439:
+	if (!discard && !obj->stolen &&
+			(obj->mm.madv != __I915_MADV_PURGED) &&

-:335: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#335: FILE: drivers/gpu/drm/i915/i915_gem.c:6449:
+	i915_error_printf(m,
+		"%p: %7zdK  %10zdK     %c      %c     %s      %s      %s     %s     %s",

-:368: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#368: FILE: drivers/gpu/drm/i915/i915_gem.c:6482:
+		i915_error_printf(m, " (%d: %d)",
+			   pid_info_entry->tgid,

-:389: CHECK:BRACES: Blank lines aren't necessary after an open brace '{'
#389: FILE: drivers/gpu/drm/i915/i915_gem.c:6503:
+	list_for_each_entry(pid_info, &obj->pid_info, head) {
+

-:435: CHECK:CONCATENATED_STRING: Concatenated strings should use spaces between elements
#435: FILE: drivers/gpu/drm/i915/i915_gem.c:6792:
+	i915_error_printf(m, "%"SPACES_STR(NUM_SPACES)"s\n", " ");

-:438: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#438: FILE: drivers/gpu/drm/i915/i915_gem.c:6795:
+	err_puts(m,
+		"\n Obj Identifier   Obj-Size Resident-Size Pin Tiling Dirty Shared Vmap Stolen Mappable  AllocState Global/PP  GttOffset (PID: handle count)\n");

-:448: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#448: FILE: drivers/gpu/drm/i915/i915_gem.c:6805:
+		ret = idr_for_each(&file->object_idr,
+				&i915_drm_gem_obj_info, &obj_stat_buf);

-:460: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#460: FILE: drivers/gpu/drm/i915/i915_gem.c:6817:
+	i915_error_printf(m, "%5d %8zdK ", pid_nr(tgid),
+			(pid_entry.stats.phys_space_shared_proportion +

-:461: CHECK:SPACING: spaces preferred around that '/' (ctx:VxV)
#461: FILE: drivers/gpu/drm/i915/i915_gem.c:6818:
+			 pid_entry.stats.phys_space_allocated_priv)/1024);
 			                                           ^

-:468: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#468: FILE: drivers/gpu/drm/i915/i915_gem.c:6825:
+		drm_ht_remove_item(&pid_entry.namelist,
+				&entry->hash_item);

-:489: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#489: FILE: drivers/gpu/drm/i915/i915_gem.c:6863:
+int i915_gem_get_obj_info(struct drm_i915_error_state_buf *m,
+			struct drm_device *dev, struct pid *tgid)

-:512: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#512: FILE: drivers/gpu/drm/i915/i915_gpu_error.c:863:
+int i915_obj_state_buf_init(struct drm_i915_error_state_buf *ebuf,
+				size_t count)

-:518: CHECK:COMPARISON_TO_NULL: Comparison to NULL could be written "!ebuf->buf"
#518: FILE: drivers/gpu/drm/i915/i915_gpu_error.c:869:
+	if (ebuf->buf == NULL)

-:549: CHECK:LINE_SPACING: Please use a blank line after function/struct/union/enum declarations
#549: FILE: drivers/gpu/drm/i915/i915_sysfs.c:585:
 }
+#define GEM_OBJ_STAT_BUF_SIZE (4*1024) /* 4KB */

-:549: CHECK:SPACING: spaces preferred around that '*' (ctx:VxV)
#549: FILE: drivers/gpu/drm/i915/i915_sysfs.c:585:
+#define GEM_OBJ_STAT_BUF_SIZE (4*1024) /* 4KB */
                                 ^

-:550: CHECK:SPACING: spaces preferred around that '*' (ctx:VxV)
#550: FILE: drivers/gpu/drm/i915/i915_sysfs.c:586:
+#define GEM_OBJ_STAT_BUF_SIZE_MAX (1024*1024) /* 1MB */
                                        ^

-:559: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#559: FILE: drivers/gpu/drm/i915/i915_sysfs.c:595:
+static ssize_t i915_gem_read_objects(struct file *filp,
+				struct kobject *memtrack_kobj,

-:601: CHECK:OPEN_ENDED_LINE: Lines should not end with a '('
#601: FILE: drivers/gpu/drm/i915/i915_sysfs.c:637:
+		DRM_ERROR(

-:610: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#610: FILE: drivers/gpu/drm/i915/i915_sysfs.c:646:
+			ret = i915_obj_state_buf_init(&attr_priv->buf,
+				buf_size);

-:612: CHECK:OPEN_ENDED_LINE: Lines should not end with a '('
#612: FILE: drivers/gpu/drm/i915/i915_sysfs.c:648:
+				DRM_ERROR(

-:643: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#643: FILE: drivers/gpu/drm/i915/i915_sysfs.c:679:
+			ret = i915_obj_state_buf_init(&attr_priv->buf,
+						buf_size);

-:645: CHECK:OPEN_ENDED_LINE: Lines should not end with a '('
#645: FILE: drivers/gpu/drm/i915/i915_sysfs.c:681:
+				DRM_ERROR(

-:657: CHECK:BRACES: braces {} should be used on all arms of this statement
#657: FILE: drivers/gpu/drm/i915/i915_sysfs.c:693:
+	if (bytes_available > 0) {
[...]
+	} else
[...]

-:660: CHECK:BRACES: Unbalanced braces around else statement
#660: FILE: drivers/gpu/drm/i915/i915_sysfs.c:696:
+	} else

-:690: WARNING:SYMBOLIC_PERMS: Symbolic permissions 'S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH' are not preferred. Consider using octal permissions '0644'.
#690: FILE: drivers/gpu/drm/i915/i915_sysfs.c:726:
+	obj_attr->attr.mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;

-:700: CHECK:OPEN_ENDED_LINE: Lines should not end with a '('
#700: FILE: drivers/gpu/drm/i915/i915_sysfs.c:736:
+		DRM_ERROR(

-:723: CHECK:COMPARISON_TO_NULL: Comparison to NULL could be written "!obj_attr"
#723: FILE: drivers/gpu/drm/i915/i915_sysfs.c:759:
+	if (WARN_ON(obj_attr == NULL))

total: 0 errors, 1 warnings, 34 checks, 664 lines checked
486204b0dac9 drm/i915: Output the user virtual addresses for GFX buffers
-:97: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#97: FILE: drivers/gpu/drm/i915/i915_gem.c:6345:
+				list_for_each_entry_safe(virt_entry,
+						virt_next,

-:165: CHECK:COMPARISON_TO_NULL: Comparison to NULL could be written "!new_entry"
#165: FILE: drivers/gpu/drm/i915/i915_gem.c:6426:
+			if (new_entry == NULL) {

-:172: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#172: FILE: drivers/gpu/drm/i915/i915_gem.c:6433:
+			list_add_tail(&new_entry->head,
+				&pid_entry->virt_addr_head);

-:212: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#212: FILE: drivers/gpu/drm/i915/i915_gem.c:6579:
+				err_printf(m, " %p",
+				(void *)(virt_entry->user_virt_addr & ~1));

-:215: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#215: FILE: drivers/gpu/drm/i915/i915_gem.c:6582:
+				err_printf(m, " %p*",
+				(void *)virt_entry->user_virt_addr);

total: 0 errors, 0 warnings, 5 checks, 199 lines checked
05a4782cc77f drm/i915: Update process mm stats for Gen GFX memory
-:80: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#80: FILE: drivers/gpu/drm/i915/i915_gem.c:6306:
+		add_mm_counter(pid_entry->attr_priv->mm, MM_FILEPAGES,
+				new_size - old_size);

-:248: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#248: FILE: drivers/gpu/drm/i915/i915_sysfs.c:770:
+		add_mm_counter(attr_priv->mm, MM_FILEPAGES,
+				-attr_priv->rss_size);

total: 0 errors, 0 warnings, 2 checks, 192 lines checked

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 11+ messages in thread

* ✗ Fi.CI.SPARSE: warning for drm/i915: Interface to get GFX shmem usage stats per process
  2018-03-22 14:14 [RFC 0/5] drm/i915: Interface to get GFX shmem usage stats per process Praveen Paneri
                   ` (5 preceding siblings ...)
  2018-03-22 14:45 ` ✗ Fi.CI.CHECKPATCH: warning for drm/i915: Interface to get GFX shmem usage stats per process Patchwork
@ 2018-03-22 14:47 ` Patchwork
  2018-03-22 15:07 ` ✗ Fi.CI.BAT: failure " Patchwork
  7 siblings, 0 replies; 11+ messages in thread
From: Patchwork @ 2018-03-22 14:47 UTC (permalink / raw)
  To: Praveen Paneri; +Cc: intel-gfx

== Series Details ==

Series: drm/i915: Interface to get GFX shmem usage stats per process
URL   : https://patchwork.freedesktop.org/series/40464/
State : warning

== Summary ==

$ dim sparse origin/drm-tip
Commit: drm/i915: Sysfs interface to get GFX shmem usage stats per process
Okay!

Commit: drm/i915: Calculate total shmem GFX memory consumed
Okay!

Commit: drm/i915: Sysfs interface to get detailed GFX buffer info per process
+drivers/gpu/drm/i915/i915_gem.c:3672:5: warning: symbol 'i915_gem_client_add' was not declared. Should it be static?
+drivers/gpu/drm/i915/i915_gem.c:3713:6: warning: symbol 'i915_gem_client_remove' was not declared. Should it be static?
+drivers/gpu/drm/i915/i915_gem.c:6457:40: warning: Using plain integer as NULL pointer

Commit: drm/i915: Output the user virtual addresses for GFX buffers
Okay!

Commit: drm/i915: Update process mm stats for Gen GFX memory
Okay!

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 11+ messages in thread

* ✗ Fi.CI.BAT: failure for drm/i915: Interface to get GFX shmem usage stats per process
  2018-03-22 14:14 [RFC 0/5] drm/i915: Interface to get GFX shmem usage stats per process Praveen Paneri
                   ` (6 preceding siblings ...)
  2018-03-22 14:47 ` ✗ Fi.CI.SPARSE: " Patchwork
@ 2018-03-22 15:07 ` Patchwork
  7 siblings, 0 replies; 11+ messages in thread
From: Patchwork @ 2018-03-22 15:07 UTC (permalink / raw)
  To: Praveen Paneri; +Cc: intel-gfx

== Series Details ==

Series: drm/i915: Interface to get GFX shmem usage stats per process
URL   : https://patchwork.freedesktop.org/series/40464/
State : failure

== Summary ==

Series 40464v1 drm/i915: Interface to get GFX shmem usage stats per process
https://patchwork.freedesktop.org/api/1.0/series/40464/revisions/1/mbox/

---- Possible new issues:

Test debugfs_test:
        Subgroup read_all_entries:
                pass       -> INCOMPLETE (fi-pnv-d510)

---- Known issues:

Test kms_pipe_crc_basic:
        Subgroup suspend-read-crc-pipe-b:
                incomplete -> PASS       (fi-snb-2520m) fdo#103713

fdo#103713 https://bugs.freedesktop.org/show_bug.cgi?id=103713

fi-bdw-5557u     total:285  pass:264  dwarn:0   dfail:0   fail:0   skip:21  time:433s
fi-bdw-gvtdvm    total:285  pass:261  dwarn:0   dfail:0   fail:0   skip:24  time:441s
fi-blb-e6850     total:285  pass:220  dwarn:1   dfail:0   fail:0   skip:64  time:380s
fi-bsw-n3050     total:285  pass:239  dwarn:0   dfail:0   fail:0   skip:46  time:537s
fi-bwr-2160      total:285  pass:180  dwarn:0   dfail:0   fail:0   skip:105 time:300s
fi-bxt-dsi       total:285  pass:255  dwarn:0   dfail:0   fail:0   skip:30  time:512s
fi-bxt-j4205     total:285  pass:256  dwarn:0   dfail:0   fail:0   skip:29  time:516s
fi-byt-j1900     total:285  pass:250  dwarn:0   dfail:0   fail:0   skip:35  time:520s
fi-byt-n2820     total:285  pass:246  dwarn:0   dfail:0   fail:0   skip:39  time:511s
fi-cfl-8700k     total:285  pass:257  dwarn:0   dfail:0   fail:0   skip:28  time:408s
fi-cfl-u         total:285  pass:259  dwarn:0   dfail:0   fail:0   skip:26  time:512s
fi-cnl-drrs      total:285  pass:254  dwarn:3   dfail:0   fail:0   skip:28  time:520s
fi-cnl-y3        total:285  pass:259  dwarn:0   dfail:0   fail:0   skip:26  time:589s
fi-elk-e7500     total:285  pass:225  dwarn:1   dfail:0   fail:0   skip:59  time:424s
fi-gdg-551       total:285  pass:176  dwarn:0   dfail:0   fail:1   skip:108 time:313s
fi-glk-1         total:285  pass:257  dwarn:0   dfail:0   fail:0   skip:28  time:535s
fi-hsw-4770      total:285  pass:258  dwarn:0   dfail:0   fail:0   skip:27  time:403s
fi-ilk-650       total:285  pass:225  dwarn:0   dfail:0   fail:0   skip:60  time:425s
fi-ivb-3520m     total:285  pass:256  dwarn:0   dfail:0   fail:0   skip:29  time:473s
fi-ivb-3770      total:285  pass:252  dwarn:0   dfail:0   fail:0   skip:33  time:432s
fi-kbl-7500u     total:285  pass:260  dwarn:1   dfail:0   fail:0   skip:24  time:475s
fi-kbl-7567u     total:285  pass:265  dwarn:0   dfail:0   fail:0   skip:20  time:465s
fi-kbl-r         total:285  pass:258  dwarn:0   dfail:0   fail:0   skip:27  time:514s
fi-pnv-d510      total:3    pass:2    dwarn:0   dfail:0   fail:0   skip:0  
fi-skl-6260u     total:285  pass:265  dwarn:0   dfail:0   fail:0   skip:20  time:441s
fi-skl-6600u     total:285  pass:258  dwarn:0   dfail:0   fail:0   skip:27  time:539s
fi-skl-6700k2    total:285  pass:261  dwarn:0   dfail:0   fail:0   skip:24  time:502s
fi-skl-6770hq    total:285  pass:265  dwarn:0   dfail:0   fail:0   skip:20  time:492s
fi-skl-guc       total:285  pass:257  dwarn:0   dfail:0   fail:0   skip:28  time:428s
fi-skl-gvtdvm    total:285  pass:262  dwarn:0   dfail:0   fail:0   skip:23  time:445s
fi-snb-2520m     total:285  pass:245  dwarn:0   dfail:0   fail:0   skip:40  time:565s
fi-snb-2600      total:285  pass:245  dwarn:0   dfail:0   fail:0   skip:40  time:402s
fi-cfl-s3 failed to connect after reboot

7ae13170ff7a3e55b3f10149db1b34571d5bbd7b drm-tip: 2018y-03m-22d-14h-02m-32s UTC integration manifest
05a4782cc77f drm/i915: Update process mm stats for Gen GFX memory
486204b0dac9 drm/i915: Output the user virtual addresses for GFX buffers
0d8d278defab drm/i915: Sysfs interface to get detailed GFX buffer info per process
27bfa55dd165 drm/i915: Calculate total shmem GFX memory consumed
a2507d62bb4c drm/i915: Sysfs interface to get GFX shmem usage stats per process

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_8449/issues.html
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: ✗ Fi.CI.CHECKPATCH: warning for drm/i915: Interface to get GFX shmem usage stats per process
  2018-03-22 14:45 ` ✗ Fi.CI.CHECKPATCH: warning for drm/i915: Interface to get GFX shmem usage stats per process Patchwork
@ 2018-03-26 14:45   ` Jani Nikula
  0 siblings, 0 replies; 11+ messages in thread
From: Jani Nikula @ 2018-03-26 14:45 UTC (permalink / raw)
  To: Patchwork, Praveen Paneri; +Cc: intel-gfx

On Thu, 22 Mar 2018, Patchwork <patchwork@emeril.freedesktop.org> wrote:
> == Series Details ==
>
> Series: drm/i915: Interface to get GFX shmem usage stats per process
> URL   : https://patchwork.freedesktop.org/series/40464/
> State : warning
>
> == Summary ==
>
> $ dim checkpatch origin/drm-tip

I don't mind the foo == NULL comparisons leading to warnings
CHECK:COMPARISON_TO_NULL: Comparison to NULL could be written "!foo"

But everything else here is valid, and should be fixed before submitting
this for real.

BR,
Jani.


> a2507d62bb4c drm/i915: Sysfs interface to get GFX shmem usage stats per process
> -:228: CHECK:SPACING: spaces preferred around that '-' (ctx:VxV)
> #228: FILE: drivers/gpu/drm/i915/i915_gem.c:6118:
> +	if (res > 0 && buffer[res-1] != '\0' && len < PAGE_SIZE)
>  	                         ^
>
> -:229: CHECK:SPACING: spaces preferred around that '-' (ctx:VxV)
> #229: FILE: drivers/gpu/drm/i915/i915_gem.c:6119:
> +		buffer[res-1] = '\0';
>  		          ^
>
> -:275: CHECK:COMPARISON_TO_NULL: Comparison to NULL could be written "!entry"
> #275: FILE: drivers/gpu/drm/i915/i915_gem.c:6165:
> +		if (entry == NULL) {
>
> -:315: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
> #315: FILE: drivers/gpu/drm/i915/i915_gem.c:6205:
> +		DRM_DEBUG("Couldn't find matching tgid %d for obj %p\n",
> +				current_tgid, obj);
>
> -:329: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
> #329: FILE: drivers/gpu/drm/i915/i915_gem.c:6219:
> +static int i915_obj_find_insert_in_hash(struct drm_i915_gem_object *obj,
> +				struct pid_stat_entry *pid_entry,
>
> -:336: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
> #336: FILE: drivers/gpu/drm/i915/i915_gem.c:6226:
> +	ret = drm_ht_find_item(&pid_entry->namelist,
> +				(unsigned long)&obj->base, &hash_item);
>
> -:338: CHECK:BRACES: braces {} should be used on all arms of this statement
> #338: FILE: drivers/gpu/drm/i915/i915_gem.c:6228:
> +	if (ret) {
> [...]
> +	} else
> [...]
>
> -:341: CHECK:COMPARISON_TO_NULL: Comparison to NULL could be written "!entry"
> #341: FILE: drivers/gpu/drm/i915/i915_gem.c:6231:
> +		if (entry == NULL) {
>
> -:350: CHECK:BRACES: Unbalanced braces around else statement
> #350: FILE: drivers/gpu/drm/i915/i915_gem.c:6240:
> +	} else
>
> -:357: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
> #357: FILE: drivers/gpu/drm/i915/i915_gem.c:6247:
> +static int i915_obj_shared_count(struct drm_i915_gem_object *obj,
> +				struct pid_stat_entry *pid_entry,
>
> -:371: CHECK:BRACES: braces {} should be used on all arms of this statement
> #371: FILE: drivers/gpu/drm/i915/i915_gem.c:6261:
> +	if (!obj->base.name && !obj->base.dma_buf)
> [...]
> +	else if (obj->base.import_attach) {
> [...]
>
> -:429: CHECK:SPACING: spaces preferred around that '*' (ctx:VxV)
> #429: FILE: drivers/gpu/drm/i915/i915_gem.c:6319:
> +			i915_obj_get_shmem_pages_alloced(obj)*PAGE_SIZE;
>  			                                     ^
>
> -:439: CHECK:BRACES: braces {} should be used on all arms of this statement
> #439: FILE: drivers/gpu/drm/i915/i915_gem.c:6329:
> +			if (obj_shared_count > 1) {
> [...]
> +			} else
> [...]
>
> -:443: CHECK:BRACES: Unbalanced braces around else statement
> #443: FILE: drivers/gpu/drm/i915/i915_gem.c:6333:
> +			} else
>
> -:480: CHECK:COMPARISON_TO_NULL: Comparison to NULL could be written "!new_entry"
> #480: FILE: drivers/gpu/drm/i915/i915_gem.c:6370:
> +			if (new_entry == NULL) {
>
> -:490: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
> #490: FILE: drivers/gpu/drm/i915/i915_gem.c:6380:
> +			ret = drm_ht_create(&new_entry->namelist,
> +					DRM_DEBUG_MAGIC_HASH_ORDER);
>
> -:519: CHECK:BRACES: Blank lines aren't necessary before a close brace '}'
> #519: FILE: drivers/gpu/drm/i915/i915_gem.c:6409:
> +
> +	}
>
> -:541: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
> #541: FILE: drivers/gpu/drm/i915/i915_gem.c:6431:
> +	err_puts(m,
> +		"\n\n  pid   Total  Shared  Priv   Purgeable  Alloced  SharedPHYsize   SharedPHYprop    PrivPHYsize   PurgeablePHYsize   process\n");
>
> -:561: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
> #561: FILE: drivers/gpu/drm/i915/i915_gem.c:6451:
> +		list_for_each_entry_safe(new_pid_entry, new_temp_entry,
> +			&sorted_pid_stats, head) {
>
> -:567: WARNING:MULTILINE_DEREFERENCE: Avoid multiple line dereference - prefer 'new_pid_entry->stats.phys_space_shared_proportion'
> #567: FILE: drivers/gpu/drm/i915/i915_gem.c:6457:
> +				new_pid_entry->
> +				stats.phys_space_shared_proportion +
>
> -:572: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
> #572: FILE: drivers/gpu/drm/i915/i915_gem.c:6462:
> +				list_add_tail(&pid_entry->head,
> +					&new_pid_entry->head);
>
> -:576: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
> #576: FILE: drivers/gpu/drm/i915/i915_gem.c:6466:
> +			if (list_is_last(&new_pid_entry->head,
> +				&sorted_pid_stats)) {
>
> -:579: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
> #579: FILE: drivers/gpu/drm/i915/i915_gem.c:6469:
> +				list_add_tail(&pid_entry->head,
> +						&sorted_pid_stats);
>
> -:585: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
> #585: FILE: drivers/gpu/drm/i915/i915_gem.c:6475:
> +	list_for_each_entry_safe(pid_entry, temp_entry,
> +				&sorted_pid_stats, head) {
>
> -:589: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
> #589: FILE: drivers/gpu/drm/i915/i915_gem.c:6479:
> +		err_printf(m,
> +			"%5d %6d %6d %6d %9d %8d %14zdK %14zdK %14zdK  %14zdK     %s",
>
> -:596: CHECK:SPACING: spaces preferred around that '/' (ctx:VxV)
> #596: FILE: drivers/gpu/drm/i915/i915_gem.c:6486:
> +			   pid_entry->stats.phys_space_allocated_shared/1024,
>  			                                               ^
>
> -:597: CHECK:SPACING: spaces preferred around that '/' (ctx:VxV)
> #597: FILE: drivers/gpu/drm/i915/i915_gem.c:6487:
> +			   pid_entry->stats.phys_space_shared_proportion/1024,
>  			                                                ^
>
> -:598: CHECK:SPACING: spaces preferred around that '/' (ctx:VxV)
> #598: FILE: drivers/gpu/drm/i915/i915_gem.c:6488:
> +			   pid_entry->stats.phys_space_allocated_priv/1024,
>  			                                             ^
>
> -:599: CHECK:SPACING: spaces preferred around that '/' (ctx:VxV)
> #599: FILE: drivers/gpu/drm/i915/i915_gem.c:6489:
> +			   pid_entry->stats.phys_space_purgeable/1024,
>  			                                        ^
>
> -:602: CHECK:COMPARISON_TO_NULL: Comparison to NULL could be written "!task"
> #602: FILE: drivers/gpu/drm/i915/i915_gem.c:6492:
> +		if (task == NULL)
>
> -:608: CHECK:SPACING: spaces preferred around that '/' (ctx:VxV)
> #608: FILE: drivers/gpu/drm/i915/i915_gem.c:6498:
> +			pid_entry->stats.phys_space_shared_proportion/1024;
>  			                                             ^
>
> -:610: CHECK:SPACING: spaces preferred around that '/' (ctx:VxV)
> #610: FILE: drivers/gpu/drm/i915/i915_gem.c:6500:
> +			pid_entry->stats.phys_space_allocated_priv/1024;
>  			                                          ^
>
> -:614: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
> #614: FILE: drivers/gpu/drm/i915/i915_gem.c:6504:
> +		list_for_each_entry_safe(entry, next,
> +					&pid_entry->namefree, head) {
>
> -:617: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
> #617: FILE: drivers/gpu/drm/i915/i915_gem.c:6507:
> +			drm_ht_remove_item(&pid_entry->namelist,
> +					&entry->hash_item);
>
> -:628: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
> #628: FILE: drivers/gpu/drm/i915/i915_gem.c:6518:
> +	err_puts(m,
> +		"\t\t\t\t\t\t\t\t--------------\t-------------\t--------\n");
>
> -:630: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
> #630: FILE: drivers/gpu/drm/i915/i915_gem.c:6520:
> +	err_printf(m,
> +		"\t\t\t\t\t\t\t\t%13zdK\t%12zdK\tTotal\n",
>
> -:754: CHECK:LINE_SPACING: Please use a blank line after function/struct/union/enum declarations
> #754: FILE: drivers/gpu/drm/i915/i915_sysfs.c:555:
>  }
> +static ssize_t i915_gem_clients_state_read(struct file *filp,
>
> -:755: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
> #755: FILE: drivers/gpu/drm/i915/i915_sysfs.c:556:
> +static ssize_t i915_gem_clients_state_read(struct file *filp,
> +				struct kobject *memtrack_kobj,
>
> -:791: CHECK:LINE_SPACING: Please use a blank line after function/struct/union/enum declarations
> #791: FILE: drivers/gpu/drm/i915/i915_sysfs.c:593:
>  };
> +static struct bin_attribute i915_gem_client_state_attr = {
>
> -:793: WARNING:SYMBOLIC_PERMS: Symbolic permissions 'S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH' are not preferred. Consider using octal permissions '0644'.
> #793: FILE: drivers/gpu/drm/i915/i915_sysfs.c:595:
> +	.attr.mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH,
>
> -:819: CHECK:OPEN_ENDED_LINE: Lines should not end with a '('
> #819: FILE: drivers/gpu/drm/i915/i915_sysfs.c:621:
> +		ret = kobject_init_and_add(
>
> -:823: CHECK:OPEN_ENDED_LINE: Lines should not end with a '('
> #823: FILE: drivers/gpu/drm/i915/i915_sysfs.c:625:
> +			DRM_ERROR(
>
> -:829: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
> #829: FILE: drivers/gpu/drm/i915/i915_sysfs.c:631:
> +			ret = sysfs_create_bin_file(&dev_priv->memtrack_kobj,
> +					    &i915_gem_client_state_attr);
>
> -:831: CHECK:OPEN_ENDED_LINE: Lines should not end with a '('
> #831: FILE: drivers/gpu/drm/i915/i915_sysfs.c:633:
> +				DRM_ERROR(
>
> -:847: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
> #847: FILE: drivers/gpu/drm/i915/i915_sysfs.c:718:
> +		sysfs_remove_bin_file(&dev_priv->memtrack_kobj,
> +					&i915_gem_client_state_attr);
>
> total: 0 errors, 2 warnings, 43 checks, 766 lines checked
> 27bfa55dd165 drm/i915: Calculate total shmem GFX memory consumed
> -:84: CHECK:UNNECESSARY_PARENTHESES: Unnecessary parentheses around 'obj->has_backing_pages == 1'
> #84: FILE: drivers/gpu/drm/i915/i915_gem.c:4884:
> +		if (!obj->stolen && (obj->has_backing_pages == 1)) {
>
> -:126: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
> #126: FILE: drivers/gpu/drm/i915/i915_gem.c:6554:
> +	err_printf(m, "\nTotal used GFX Shmem Physical space %8zdK\n",
> +		  dev_priv->mm.phys_mem_total/1024);
>
> -:126: CHECK:SPACING: spaces preferred around that '/' (ctx:VxV)
> #126: FILE: drivers/gpu/drm/i915/i915_gem.c:6554:
> +		  dev_priv->mm.phys_mem_total/1024);
>  		                             ^
>
> total: 0 errors, 0 warnings, 3 checks, 101 lines checked
> 0d8d278defab drm/i915: Sysfs interface to get detailed GFX buffer info per process
> -:167: CHECK:COMPARISON_TO_NULL: Comparison to NULL could be written "!client_pid"
> #167: FILE: drivers/gpu/drm/i915/i915_gem.c:3689:
> +		if (client_pid == NULL) {
>
> -:175: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
> #175: FILE: drivers/gpu/drm/i915/i915_gem.c:3697:
> +		ret = i915_gem_create_sysfs_file_entry(&i915->drm,
> +						 &client_pid->obj_attr);
>
> -:187: CHECK:BRACES: Blank lines aren't necessary before a close brace '}'
> #187: FILE: drivers/gpu/drm/i915/i915_gem.c:3709:
> +
> +	}
>
> -:201: CHECK:UNNECESSARY_PARENTHESES: Unnecessary parentheses around 'client_pid->tgid == tgid'
> #201: FILE: drivers/gpu/drm/i915/i915_gem.c:3723:
> +		if ((client_pid->tgid == tgid) &&
> +		    (--client_pid->open_obj_count == 0)) {
>
> -:249: CHECK:LINE_SPACING: Please don't use multiple blank lines
> #249: FILE: drivers/gpu/drm/i915/i915_gem.c:3790:
>  
> +
>
> -:322: CHECK:SPACING: spaces preferred around that '*' (ctx:VxV)
> #322: FILE: drivers/gpu/drm/i915/i915_gem.c:6436:
> +		nr_bytes = i915_obj_get_shmem_pages_alloced(obj)*PAGE_SIZE;
>  		                                                ^
>
> -:324: CHECK:UNNECESSARY_PARENTHESES: Unnecessary parentheses around 'obj->mm.madv != __I915_MADV_PURGED'
> #324: FILE: drivers/gpu/drm/i915/i915_gem.c:6438:
> +	if (!discard && !obj->stolen &&
> +			(obj->mm.madv != __I915_MADV_PURGED) &&
> +			(nr_bytes != 0)) {
>
> -:324: CHECK:UNNECESSARY_PARENTHESES: Unnecessary parentheses around 'nr_bytes != 0'
> #324: FILE: drivers/gpu/drm/i915/i915_gem.c:6438:
> +	if (!discard && !obj->stolen &&
> +			(obj->mm.madv != __I915_MADV_PURGED) &&
> +			(nr_bytes != 0)) {
>
> -:325: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
> #325: FILE: drivers/gpu/drm/i915/i915_gem.c:6439:
> +	if (!discard && !obj->stolen &&
> +			(obj->mm.madv != __I915_MADV_PURGED) &&
>
> -:335: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
> #335: FILE: drivers/gpu/drm/i915/i915_gem.c:6449:
> +	i915_error_printf(m,
> +		"%p: %7zdK  %10zdK     %c      %c     %s      %s      %s     %s     %s",
>
> -:368: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
> #368: FILE: drivers/gpu/drm/i915/i915_gem.c:6482:
> +		i915_error_printf(m, " (%d: %d)",
> +			   pid_info_entry->tgid,
>
> -:389: CHECK:BRACES: Blank lines aren't necessary after an open brace '{'
> #389: FILE: drivers/gpu/drm/i915/i915_gem.c:6503:
> +	list_for_each_entry(pid_info, &obj->pid_info, head) {
> +
>
> -:435: CHECK:CONCATENATED_STRING: Concatenated strings should use spaces between elements
> #435: FILE: drivers/gpu/drm/i915/i915_gem.c:6792:
> +	i915_error_printf(m, "%"SPACES_STR(NUM_SPACES)"s\n", " ");
>
> -:438: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
> #438: FILE: drivers/gpu/drm/i915/i915_gem.c:6795:
> +	err_puts(m,
> +		"\n Obj Identifier   Obj-Size Resident-Size Pin Tiling Dirty Shared Vmap Stolen Mappable  AllocState Global/PP  GttOffset (PID: handle count)\n");
>
> -:448: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
> #448: FILE: drivers/gpu/drm/i915/i915_gem.c:6805:
> +		ret = idr_for_each(&file->object_idr,
> +				&i915_drm_gem_obj_info, &obj_stat_buf);
>
> -:460: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
> #460: FILE: drivers/gpu/drm/i915/i915_gem.c:6817:
> +	i915_error_printf(m, "%5d %8zdK ", pid_nr(tgid),
> +			(pid_entry.stats.phys_space_shared_proportion +
>
> -:461: CHECK:SPACING: spaces preferred around that '/' (ctx:VxV)
> #461: FILE: drivers/gpu/drm/i915/i915_gem.c:6818:
> +			 pid_entry.stats.phys_space_allocated_priv)/1024);
>  			                                           ^
>
> -:468: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
> #468: FILE: drivers/gpu/drm/i915/i915_gem.c:6825:
> +		drm_ht_remove_item(&pid_entry.namelist,
> +				&entry->hash_item);
>
> -:489: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
> #489: FILE: drivers/gpu/drm/i915/i915_gem.c:6863:
> +int i915_gem_get_obj_info(struct drm_i915_error_state_buf *m,
> +			struct drm_device *dev, struct pid *tgid)
>
> -:512: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
> #512: FILE: drivers/gpu/drm/i915/i915_gpu_error.c:863:
> +int i915_obj_state_buf_init(struct drm_i915_error_state_buf *ebuf,
> +				size_t count)
>
> -:518: CHECK:COMPARISON_TO_NULL: Comparison to NULL could be written "!ebuf->buf"
> #518: FILE: drivers/gpu/drm/i915/i915_gpu_error.c:869:
> +	if (ebuf->buf == NULL)
>
> -:549: CHECK:LINE_SPACING: Please use a blank line after function/struct/union/enum declarations
> #549: FILE: drivers/gpu/drm/i915/i915_sysfs.c:585:
>  }
> +#define GEM_OBJ_STAT_BUF_SIZE (4*1024) /* 4KB */
>
> -:549: CHECK:SPACING: spaces preferred around that '*' (ctx:VxV)
> #549: FILE: drivers/gpu/drm/i915/i915_sysfs.c:585:
> +#define GEM_OBJ_STAT_BUF_SIZE (4*1024) /* 4KB */
>                                  ^
>
> -:550: CHECK:SPACING: spaces preferred around that '*' (ctx:VxV)
> #550: FILE: drivers/gpu/drm/i915/i915_sysfs.c:586:
> +#define GEM_OBJ_STAT_BUF_SIZE_MAX (1024*1024) /* 1MB */
>                                         ^
>
> -:559: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
> #559: FILE: drivers/gpu/drm/i915/i915_sysfs.c:595:
> +static ssize_t i915_gem_read_objects(struct file *filp,
> +				struct kobject *memtrack_kobj,
>
> -:601: CHECK:OPEN_ENDED_LINE: Lines should not end with a '('
> #601: FILE: drivers/gpu/drm/i915/i915_sysfs.c:637:
> +		DRM_ERROR(
>
> -:610: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
> #610: FILE: drivers/gpu/drm/i915/i915_sysfs.c:646:
> +			ret = i915_obj_state_buf_init(&attr_priv->buf,
> +				buf_size);
>
> -:612: CHECK:OPEN_ENDED_LINE: Lines should not end with a '('
> #612: FILE: drivers/gpu/drm/i915/i915_sysfs.c:648:
> +				DRM_ERROR(
>
> -:643: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
> #643: FILE: drivers/gpu/drm/i915/i915_sysfs.c:679:
> +			ret = i915_obj_state_buf_init(&attr_priv->buf,
> +						buf_size);
>
> -:645: CHECK:OPEN_ENDED_LINE: Lines should not end with a '('
> #645: FILE: drivers/gpu/drm/i915/i915_sysfs.c:681:
> +				DRM_ERROR(
>
> -:657: CHECK:BRACES: braces {} should be used on all arms of this statement
> #657: FILE: drivers/gpu/drm/i915/i915_sysfs.c:693:
> +	if (bytes_available > 0) {
> [...]
> +	} else
> [...]
>
> -:660: CHECK:BRACES: Unbalanced braces around else statement
> #660: FILE: drivers/gpu/drm/i915/i915_sysfs.c:696:
> +	} else
>
> -:690: WARNING:SYMBOLIC_PERMS: Symbolic permissions 'S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH' are not preferred. Consider using octal permissions '0644'.
> #690: FILE: drivers/gpu/drm/i915/i915_sysfs.c:726:
> +	obj_attr->attr.mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
>
> -:700: CHECK:OPEN_ENDED_LINE: Lines should not end with a '('
> #700: FILE: drivers/gpu/drm/i915/i915_sysfs.c:736:
> +		DRM_ERROR(
>
> -:723: CHECK:COMPARISON_TO_NULL: Comparison to NULL could be written "!obj_attr"
> #723: FILE: drivers/gpu/drm/i915/i915_sysfs.c:759:
> +	if (WARN_ON(obj_attr == NULL))
>
> total: 0 errors, 1 warnings, 34 checks, 664 lines checked
> 486204b0dac9 drm/i915: Output the user virtual addresses for GFX buffers
> -:97: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
> #97: FILE: drivers/gpu/drm/i915/i915_gem.c:6345:
> +				list_for_each_entry_safe(virt_entry,
> +						virt_next,
>
> -:165: CHECK:COMPARISON_TO_NULL: Comparison to NULL could be written "!new_entry"
> #165: FILE: drivers/gpu/drm/i915/i915_gem.c:6426:
> +			if (new_entry == NULL) {
>
> -:172: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
> #172: FILE: drivers/gpu/drm/i915/i915_gem.c:6433:
> +			list_add_tail(&new_entry->head,
> +				&pid_entry->virt_addr_head);
>
> -:212: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
> #212: FILE: drivers/gpu/drm/i915/i915_gem.c:6579:
> +				err_printf(m, " %p",
> +				(void *)(virt_entry->user_virt_addr & ~1));
>
> -:215: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
> #215: FILE: drivers/gpu/drm/i915/i915_gem.c:6582:
> +				err_printf(m, " %p*",
> +				(void *)virt_entry->user_virt_addr);
>
> total: 0 errors, 0 warnings, 5 checks, 199 lines checked
> 05a4782cc77f drm/i915: Update process mm stats for Gen GFX memory
> -:80: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
> #80: FILE: drivers/gpu/drm/i915/i915_gem.c:6306:
> +		add_mm_counter(pid_entry->attr_priv->mm, MM_FILEPAGES,
> +				new_size - old_size);
>
> -:248: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
> #248: FILE: drivers/gpu/drm/i915/i915_sysfs.c:770:
> +		add_mm_counter(attr_priv->mm, MM_FILEPAGES,
> +				-attr_priv->rss_size);
>
> total: 0 errors, 0 warnings, 2 checks, 192 lines checked
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Jani Nikula, Intel Open Source Technology Center
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2018-03-26 14:44 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-03-22 14:14 [RFC 0/5] drm/i915: Interface to get GFX shmem usage stats per process Praveen Paneri
2018-03-22 14:14 ` [RFC 1/5] drm/i915: Sysfs interface " Praveen Paneri
2018-03-22 14:15   ` Chris Wilson
2018-03-22 14:14 ` [RFC 2/5] drm/i915: Calculate total shmem GFX memory consumed Praveen Paneri
2018-03-22 14:14 ` [RFC 3/5] drm/i915: Sysfs interface to get detailed GFX buffer info per process Praveen Paneri
2018-03-22 14:14 ` [RFC 4/5] drm/i915: Output the user virtual addresses for GFX buffers Praveen Paneri
2018-03-22 14:14 ` [RFC 5/5] drm/i915: Update process mm stats for Gen GFX memory Praveen Paneri
2018-03-22 14:45 ` ✗ Fi.CI.CHECKPATCH: warning for drm/i915: Interface to get GFX shmem usage stats per process Patchwork
2018-03-26 14:45   ` Jani Nikula
2018-03-22 14:47 ` ✗ Fi.CI.SPARSE: " Patchwork
2018-03-22 15:07 ` ✗ Fi.CI.BAT: failure " Patchwork

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.