From patchwork Wed Aug 29 03:52:20 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zhangfei Gao X-Patchwork-Id: 11031 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id DAE3823E29 for ; Wed, 29 Aug 2012 14:01:14 +0000 (UTC) Received: from mail-ie0-f180.google.com (mail-ie0-f180.google.com [209.85.223.180]) by fiordland.canonical.com (Postfix) with ESMTP id 12AB5A181E9 for ; Wed, 29 Aug 2012 14:00:41 +0000 (UTC) Received: by ieak11 with SMTP id k11so196611iea.11 for ; Wed, 29 Aug 2012 07:01:13 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-forwarded-to:x-forwarded-for:delivered-to:received-spf:from:to :date:message-id:x-mailer:in-reply-to:references :x-originalarrivaltime:x-mailman-approved-at:cc:subject:x-beenthere :x-mailman-version:precedence:list-id:list-unsubscribe:list-archive :list-post:list-help:list-subscribe:mime-version:content-type :content-transfer-encoding:sender:errors-to:x-gm-message-state; bh=Fqa7cYxgFG8xZO8KbEYRtLUHiU5uz9T/BgcF/EDmCno=; b=AMZkbFgeS6KBM5CO5u6il7H516JizW24tHSZQ8oQvIHcRooNX6r9JIQvUgt69pgOaR EkYQJa8NHo+wqL2GuketmKMw3gMx0RHikx9SSrNBdQpNAElLAqGOPNpZoj0h6769iTN+ Fu4Z+W1XgA4PqpFpVBw+zV2a2novZQxNp+gOCKkJx/gWOLpDLgTE1xfqcYBP98yjik1u uELRkIv9Y8RHpbIxuMly0WjnRDQMd+QaGehb2wDdPu940Hpngg3lpVCvUZ8d85B8xyzI rNYwILaBugzU1ntpHa8ityLA8EMLdfhIwOnpxw4BMEC7F6dmuqUm2+SFTTdP3TKTYKps MgNg== Received: by 10.50.237.41 with SMTP id uz9mr1655518igc.43.1346248873864; Wed, 29 Aug 2012 07:01:13 -0700 (PDT) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.50.184.232 with SMTP id ex8csp86881igc; Wed, 29 Aug 2012 07:01:12 -0700 (PDT) Received: by 10.205.139.6 with SMTP id iu6mr1127183bkc.20.1346248871873; Wed, 29 Aug 2012 07:01:11 -0700 (PDT) Received: from mombin.canonical.com (mombin.canonical.com. [91.189.95.16]) by mx.google.com with ESMTP id ig20si15954262bkc.13.2012.08.29.07.01.09; Wed, 29 Aug 2012 07:01:11 -0700 (PDT) Received-SPF: neutral (google.com: 91.189.95.16 is neither permitted nor denied by best guess record for domain of linaro-mm-sig-bounces@lists.linaro.org) client-ip=91.189.95.16; Authentication-Results: mx.google.com; spf=neutral (google.com: 91.189.95.16 is neither permitted nor denied by best guess record for domain of linaro-mm-sig-bounces@lists.linaro.org) smtp.mail=linaro-mm-sig-bounces@lists.linaro.org Received: from localhost ([127.0.0.1] helo=mombin.canonical.com) by mombin.canonical.com with esmtp (Exim 4.71) (envelope-from ) id 1T6ipP-0003OS-EP; Wed, 29 Aug 2012 14:01:07 +0000 Received: from na3sys009aog136.obsmtp.com ([74.125.149.85]) by mombin.canonical.com with esmtp (Exim 4.71) (envelope-from ) id 1T6ZNH-0005Or-4Z for linaro-mm-sig@lists.linaro.org; Wed, 29 Aug 2012 03:55:27 +0000 Received: from MSI-MTA.marvell.com ([65.219.4.132]) (using TLSv1) by na3sys009aob136.postini.com ([74.125.148.12]) with SMTP ID DSNKUD2SrDtnsQj2/gxusgW2f+qwDKMSNqB0@postini.com; Tue, 28 Aug 2012 20:55:27 PDT Received: from maili.marvell.com ([10.68.76.210]) by MSI-MTA.marvell.com with Microsoft SMTPSVC(6.0.3790.3959); Tue, 28 Aug 2012 20:52:26 -0700 Received: from localhost (unknown [10.26.128.111]) by maili.marvell.com (Postfix) with ESMTP id E98254E510; Tue, 28 Aug 2012 20:52:25 -0700 (PDT) From: Zhangfei Gao To: Rebecca Schultz Zavin , "linaro-mm-sig@lists.linaro.org" , Haojian Zhuang Date: Wed, 29 Aug 2012 11:52:20 +0800 Message-Id: <1346212340-25236-4-git-send-email-zhangfei.gao@marvell.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1346212340-25236-1-git-send-email-zhangfei.gao@marvell.com> References: <1346212340-25236-1-git-send-email-zhangfei.gao@marvell.com> X-OriginalArrivalTime: 29 Aug 2012 03:52:26.0219 (UTC) FILETIME=[B42163B0:01CD8599] X-Mailman-Approved-At: Wed, 29 Aug 2012 14:01:04 +0000 Cc: Zhangfei Gao Subject: [Linaro-mm-sig] [PATCH 3/3] gpu: ion: oom killer X-BeenThere: linaro-mm-sig@lists.linaro.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: "Unified memory management interest group." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: linaro-mm-sig-bounces@lists.linaro.org Errors-To: linaro-mm-sig-bounces@lists.linaro.org X-Gm-Message-State: ALoCoQmT2jStEaMZz2MFl2k85IZB7ojAPLrqBVfGnDa4m+Pv84TXipWb939h5wEzf0oBrqoV++ml ion_shrink is called when ION_CARVEOUT_ALLOCATE_FAIL How to test: mount -t debugfs none /mnt cat /mnt/ion/carveout_heap echo adj > /mnt/ion/carveout_heap send_sig SIGKILL to the task with higher adj and using ion buffer Also kill all others tasks refered the buffers, in case using empty buffer Example: cat /mnt/ion/carveout_heap client pid size oom_score_adj ion_test 191 4096 0 ion_test 192 4096 0 ion_test 193 4096 0 echo -1 > /mnt/ion/carveout_heap [ 1333.689318] SIGKILL pid: 191 [ 1333.692192] SIGKILL pid: 192 [ 1333.695436] SIGKILL pid: 193 [ 1333.698312] SIGKILL pid: 193 size: 4096 adj: 0 [1]+ Killed ./ion_test 2 cat /mnt/ion/carveout_heap client pid size oom_score_adj Signed-off-by: Zhangfei Gao --- drivers/gpu/ion/ion.c | 112 +++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 109 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/ion/ion.c b/drivers/gpu/ion/ion.c index 34c12df..3edaab0 100644 --- a/drivers/gpu/ion/ion.c +++ b/drivers/gpu/ion/ion.c @@ -32,6 +32,7 @@ #include #include #include +#include #include "ion_priv.h" @@ -336,6 +337,8 @@ static void ion_handle_add(struct ion_client *client, struct ion_handle *handle) rb_insert_color(&handle->node, &client->handles); } +static int ion_shrink(struct ion_heap *heap, int kill_adj); + struct ion_handle *ion_alloc(struct ion_client *client, size_t len, size_t align, unsigned int heap_mask, unsigned int flags) @@ -367,7 +370,12 @@ struct ion_handle *ion_alloc(struct ion_client *client, size_t len, /* if the caller didn't specify this heap type */ if (!((1 << heap->id) & heap_mask)) continue; +retry: buffer = ion_buffer_create(heap, dev, len, align, flags); + if (buffer == ERR_PTR(ION_CARVEOUT_ALLOCATE_FAIL)) { + if (!ion_shrink(heap, 0)) + goto retry; + } if (!IS_ERR_OR_NULL(buffer)) break; } @@ -1144,7 +1152,8 @@ static int ion_debug_heap_show(struct seq_file *s, void *unused) struct ion_device *dev = heap->dev; struct rb_node *n; - seq_printf(s, "%16.s %16.s %16.s\n", "client", "pid", "size"); + seq_printf(s, "%16.s %16.s %16.s %16.s\n", + "client", "pid", "size", "oom_score_adj"); for (n = rb_first(&dev->clients); n; n = rb_next(n)) { struct ion_client *client = rb_entry(n, struct ion_client, @@ -1156,8 +1165,9 @@ static int ion_debug_heap_show(struct seq_file *s, void *unused) char task_comm[TASK_COMM_LEN]; get_task_comm(task_comm, client->task); - seq_printf(s, "%16.s %16u %16u\n", task_comm, - client->pid, size); + seq_printf(s, "%16.s %16u %16u %16u\n", task_comm, + client->pid, size, + client->task->signal->oom_score_adj); } else { seq_printf(s, "%16.s %16u %16u\n", client->name, client->pid, size); @@ -1171,13 +1181,109 @@ static int ion_debug_heap_open(struct inode *inode, struct file *file) return single_open(file, ion_debug_heap_show, inode->i_private); } +static ssize_t +ion_debug_heap_write(struct file *file, const char __user *ubuf, + size_t count, loff_t *ppos) +{ + struct ion_heap *heap = + ((struct seq_file *)file->private_data)->private; + char buf[16]; + long kill_adj, ret; + + memset(buf, 0, sizeof(buf)); + + if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) + return -EFAULT; + + ret = kstrtol(buf, 10, &kill_adj); + if (ret) + return ret; + + ion_shrink(heap, kill_adj); + + return count; +} static const struct file_operations debug_heap_fops = { .open = ion_debug_heap_open, + .write = ion_debug_heap_write, .read = seq_read, .llseek = seq_lseek, .release = single_release, }; +/* + * ion_shrink + * kill all tasks referd the buffer by selected task + */ +static int ion_shrink(struct ion_heap *heap, int kill_adj) +{ + struct rb_node *n; + struct ion_client *client = NULL; + struct ion_device *dev = heap->dev; + struct task_struct *selected = NULL; + int selected_size = 0; + int selected_oom_score_adj = 0; + + for (n = rb_first(&dev->clients); n; n = rb_next(n)) { + size_t size; + struct task_struct *p; + + client = rb_entry(n, struct ion_client, node); + if (!client->task) + continue; + + p = client->task; + + if ((p->signal->oom_score_adj <= kill_adj) || + (p->signal->oom_score_adj < selected_oom_score_adj)) + continue; + + size = ion_debug_heap_total(client, heap->type); + if (!size) + continue; + if (size < selected_size) + continue; + + selected = p; + selected_size = size; + selected_oom_score_adj = p->signal->oom_score_adj; + } + + if (selected) { + /* kill all proeces refer buffer shared with this client */ + mutex_lock(&client->lock); + for (n = rb_first(&client->handles); n; n = rb_next(n)) { + struct rb_node *r; + struct ion_client *c; + struct ion_handle *handle = rb_entry(n, + struct ion_handle, + node); + + for (r = rb_first(&dev->clients); r; r = rb_next(r)) { + struct ion_handle *h; + + c = rb_entry(r, struct ion_client, node); + h = ion_handle_lookup(c, handle->buffer); + if (!IS_ERR_OR_NULL(h)) { + send_sig(SIGKILL, c->task, 0); + pr_info("SIGKILL pid: %u\n", + c->task->pid); + } + + } + } + mutex_unlock(&client->lock); + + send_sig(SIGKILL, selected, 0); + set_tsk_thread_flag(selected, TIF_MEMDIE); + pr_info("SIGKILL pid: %u size: %u adj: %u\n", + selected->pid, selected_size, + selected_oom_score_adj); + return 0; + } + return -EAGAIN; +} + void ion_device_add_heap(struct ion_device *dev, struct ion_heap *heap) { struct rb_node **p = &dev->heaps.rb_node;