get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/769491/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 769491,
    "url": "http://patchwork.ozlabs.org/api/patches/769491/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/linuxppc-dev/patch/20170601053440.28976-2-rashmica.g@gmail.com/",
    "project": {
        "id": 2,
        "url": "http://patchwork.ozlabs.org/api/projects/2/?format=api",
        "name": "Linux PPC development",
        "link_name": "linuxppc-dev",
        "list_id": "linuxppc-dev.lists.ozlabs.org",
        "list_email": "linuxppc-dev@lists.ozlabs.org",
        "web_url": "https://github.com/linuxppc/wiki/wiki",
        "scm_url": "https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git",
        "webscm_url": "https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git/",
        "list_archive_url": "https://lore.kernel.org/linuxppc-dev/",
        "list_archive_url_format": "https://lore.kernel.org/linuxppc-dev/{}/",
        "commit_url_format": "https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git/commit/?id={}"
    },
    "msgid": "<20170601053440.28976-2-rashmica.g@gmail.com>",
    "list_archive_url": "https://lore.kernel.org/linuxppc-dev/20170601053440.28976-2-rashmica.g@gmail.com/",
    "date": "2017-06-01T05:34:39",
    "name": "[v3,2/3] powerpc/powernv: Enable removal of memory for in memory tracing",
    "commit_ref": "9d5171a8f248b1b0e69329bf141e17645c0324a0",
    "pull_url": null,
    "state": "accepted",
    "archived": false,
    "hash": "7d94afc1ce4e0c5baa0d8d98f1922e45ecb5af53",
    "submitter": {
        "id": 71056,
        "url": "http://patchwork.ozlabs.org/api/people/71056/?format=api",
        "name": "Rashmica Gupta",
        "email": "rashmica.g@gmail.com"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/linuxppc-dev/patch/20170601053440.28976-2-rashmica.g@gmail.com/mbox/",
    "series": [],
    "comments": "http://patchwork.ozlabs.org/api/patches/769491/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/769491/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org>",
        "X-Original-To": [
            "patchwork-incoming@ozlabs.org",
            "linuxppc-dev@lists.ozlabs.org"
        ],
        "Delivered-To": [
            "patchwork-incoming@ozlabs.org",
            "linuxppc-dev@lists.ozlabs.org"
        ],
        "Received": [
            "from lists.ozlabs.org (lists.ozlabs.org [103.22.144.68])\n\t(using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby ozlabs.org (Postfix) with ESMTPS id 3wdbhz4lclz9s89\n\tfor <patchwork-incoming@ozlabs.org>;\n\tThu,  1 Jun 2017 15:37:55 +1000 (AEST)",
            "from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3])\n\tby lists.ozlabs.org (Postfix) with ESMTP id 3wdbhz3gqtzDqFb\n\tfor <patchwork-incoming@ozlabs.org>;\n\tThu,  1 Jun 2017 15:37:55 +1000 (AEST)",
            "from mail-pf0-x243.google.com (mail-pf0-x243.google.com\n\t[IPv6:2607:f8b0:400e:c00::243])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128\n\tbits)) (No client certificate requested)\n\tby lists.ozlabs.org (Postfix) with ESMTPS id 3wdbdY0BydzDqFy\n\tfor <linuxppc-dev@lists.ozlabs.org>;\n\tThu,  1 Jun 2017 15:34:57 +1000 (AEST)",
            "by mail-pf0-x243.google.com with SMTP id w69so6541877pfk.1\n\tfor <linuxppc-dev@lists.ozlabs.org>;\n\tWed, 31 May 2017 22:34:56 -0700 (PDT)",
            "from rashmica.ozlabs.ibm.com ([122.99.82.10])\n\tby smtp.gmail.com with ESMTPSA id\n\tt17sm29353697pfj.61.2017.05.31.22.34.51\n\t(version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128);\n\tWed, 31 May 2017 22:34:54 -0700 (PDT)"
        ],
        "Authentication-Results": [
            "ozlabs.org; dkim=pass (2048-bit key;\n\tunprotected) header.d=gmail.com header.i=@gmail.com\n\theader.b=\"UEy6c3a3\"; dkim-atps=neutral",
            "lists.ozlabs.org; dkim=pass (2048-bit key;\n\tunprotected) header.d=gmail.com header.i=@gmail.com\n\theader.b=\"UEy6c3a3\"; dkim-atps=neutral",
            "lists.ozlabs.org; dkim=pass (2048-bit key;\n\tunprotected) header.d=gmail.com header.i=@gmail.com\n\theader.b=\"UEy6c3a3\"; dkim-atps=neutral"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025;\n\th=from:to:cc:subject:date:message-id:in-reply-to:references;\n\tbh=ot+AKawfXVYx6G6PXKkAgJaA+jAXTlLDdf0y1CYrDLA=;\n\tb=UEy6c3a3YsJ4h96PvD+0noM6DH0hRrMx+iPz/lH+uL7u0rSsKWuQE4ia2ZVQf3tz18\n\tfFnwRnBPAXBgvH255UWGx5jK7tzu74jViYq5r6xOxoMm55BnSliv8D2wxRkw7r9b/ufL\n\tCXRWUWbMtJkaDHhKdvyp6/sg+3XIruXn648MycfaXvHxO5htweCJ8Nhuso4cvjR2Hd2v\n\tHaI034JWXRFAFKIMDTpOvc0YyeKKHvMik5Vu4y/RaE1z+qHBKdEMMQb5+xcqJxV3NEMA\n\tu3n6UFdZTYe4HJ3LA92i7WCNpKzhgNmJlDZ0wzOTOqJaeCPCoap15CEfqskVfA/uAIUp\n\tI2UA==",
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to\n\t:references;\n\tbh=ot+AKawfXVYx6G6PXKkAgJaA+jAXTlLDdf0y1CYrDLA=;\n\tb=qlYget7xh0nqGCuBKnZPTCU5ZR8+rZbJur1sVZgSCccDXIao5Wb4Bl3fJHbaw4NNzW\n\toSf5+z/mWLgR2CmoHPiR3wR4t39XnPwgZR2rT6g6DaqRuX6pjWP424eXX04joL1aSCUs\n\tsEgsUWudvgXNUAGcUDJue23Nr5oZJhAWkhhs90VXTULzmb9KGvzrCpL+LuVWlp4JQt/Q\n\tyzTaL6lHkLxSz2uGh8id5qyxVxqdHyZsb5JRKyWGbuLcyl9kWWVbM9GRtE79IzEx/53C\n\toGxMj4owHISeFwtmvcG2phTEmGjwfsGrfKBWRWnqIQPqL0L2q6b5fGLWQsahqyFXJM8M\n\tJrbQ==",
        "X-Gm-Message-State": "AODbwcAr2xeUUYbhtTid32iHx3GgC7ik6FZ3qMiIgdlUtImXU+leTUiq\n\t7tHHxA61y3UF7ukXmEw=",
        "X-Received": "by 10.99.113.11 with SMTP id m11mr37024484pgc.45.1496295295107; \n\tWed, 31 May 2017 22:34:55 -0700 (PDT)",
        "From": "Rashmica Gupta <rashmica.g@gmail.com>",
        "To": "linuxppc-dev@lists.ozlabs.org, mpe@ellerman.id.au, anton@samba.org,\n\tnpiggin@gmail.com, bsingharora@gmail.com, oohall@gmail.com,\n\tkhandual@linux.vnet.ibm.com",
        "Subject": "[PATCH v3 2/3] powerpc/powernv: Enable removal of memory for in\n\tmemory tracing",
        "Date": "Thu,  1 Jun 2017 15:34:39 +1000",
        "Message-Id": "<20170601053440.28976-2-rashmica.g@gmail.com>",
        "X-Mailer": "git-send-email 2.9.3",
        "In-Reply-To": "<20170601053440.28976-1-rashmica.g@gmail.com>",
        "References": "<20170601053440.28976-1-rashmica.g@gmail.com>",
        "X-BeenThere": "linuxppc-dev@lists.ozlabs.org",
        "X-Mailman-Version": "2.1.23",
        "Precedence": "list",
        "List-Id": "Linux on PowerPC Developers Mail List\n\t<linuxppc-dev.lists.ozlabs.org>",
        "List-Unsubscribe": "<https://lists.ozlabs.org/options/linuxppc-dev>,\n\t<mailto:linuxppc-dev-request@lists.ozlabs.org?subject=unsubscribe>",
        "List-Archive": "<http://lists.ozlabs.org/pipermail/linuxppc-dev/>",
        "List-Post": "<mailto:linuxppc-dev@lists.ozlabs.org>",
        "List-Help": "<mailto:linuxppc-dev-request@lists.ozlabs.org?subject=help>",
        "List-Subscribe": "<https://lists.ozlabs.org/listinfo/linuxppc-dev>,\n\t<mailto:linuxppc-dev-request@lists.ozlabs.org?subject=subscribe>",
        "Cc": "Rashmica Gupta <rashmica.g@gmail.com>",
        "Errors-To": "linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org",
        "Sender": "\"Linuxppc-dev\"\n\t<linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org>"
    },
    "content": "The hardware trace macro feature requires access to a chunk of real\nmemory. This patch provides a debugfs interface to do this. By\nwriting an integer containing the size of memory to be unplugged into\n/sys/kernel/debug/powerpc/memtrace/enable, the code will attempt to\nremove that much memory from the end of each NUMA node.\n\nThis patch also adds additional debugsfs files for each node that\nallows the tracer to interact with the removed memory, as well as\na trace file that allows userspace to read the generated trace.\n\nNote that this patch does not invoke the hardware trace macro, it\nonly allows memory to be removed during runtime for the trace macro\nto utilise.\n\nSigned-off-by: Rashmica Gupta <rashmica.g@gmail.com>\n---\nv2 -> v3 : - Some changes required to compile with 4.12-rc3.\n\t- Iterating from end of node rather than the start.\n\t- As io_remap_pfn_range is defined as remap_pfn_range, just use remap_pfn_range.\n\t- Removed the creation of the node debugsfs file as it had no use.\n\n arch/powerpc/platforms/powernv/memtrace.c | 289 ++++++++++++++++++++++++++++++\n 1 file changed, 289 insertions(+)\n create mode 100644 arch/powerpc/platforms/powernv/memtrace.c",
    "diff": "diff --git a/arch/powerpc/platforms/powernv/memtrace.c b/arch/powerpc/platforms/powernv/memtrace.c\nnew file mode 100644\nindex 0000000..21fa2e4\n--- /dev/null\n+++ b/arch/powerpc/platforms/powernv/memtrace.c\n@@ -0,0 +1,289 @@\n+/*\n+ * This program is free software; you can redistribute it and/or modify\n+ * it under the terms of the GNU General Public License as published by\n+ * the Free Software Foundation; either version 2 of the License, or\n+ * (at your option) any later version.\n+ *\n+ * This program is distributed in the hope that it will be useful,\n+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\n+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n+ * GNU General Public License for more details.\n+ *\n+ * Copyright (C) IBM Corporation, 2014\n+ *\n+ * Author: Anton Blanchard <anton@au.ibm.com>\n+ */\n+\n+#define pr_fmt(fmt) \"powernv-memtrace: \" fmt\n+\n+#include <linux/bitops.h>\n+#include <linux/string.h>\n+#include <linux/memblock.h>\n+#include <linux/init.h>\n+#include <linux/moduleparam.h>\n+#include <linux/fs.h>\n+#include <linux/debugfs.h>\n+#include <linux/slab.h>\n+#include <linux/memory.h>\n+#include <linux/memory_hotplug.h>\n+#include <asm/machdep.h>\n+#include <asm/debugfs.h>\n+\n+/* This enables us to keep track of the memory removed from each node. */\n+struct memtrace_entry {\n+\tvoid *mem;\n+\tu64 start;\n+\tu64 size;\n+\tu32 nid;\n+\tstruct dentry *dir;\n+\tchar name[16];\n+};\n+\n+static struct memtrace_entry *memtrace_array;\n+static unsigned int memtrace_array_nr;\n+\n+static ssize_t memtrace_read(struct file *filp, char __user *ubuf,\n+\t\t\t     size_t count, loff_t *ppos)\n+{\n+\tstruct memtrace_entry *ent = filp->private_data;\n+\n+\treturn simple_read_from_buffer(ubuf, count, ppos, ent->mem, ent->size);\n+}\n+\n+static bool valid_memtrace_range(struct memtrace_entry *dev,\n+\t\t\t\t unsigned long start, unsigned long size)\n+{\n+\tif ((start >= dev->start) &&\n+\t    ((start + size) <= (dev->start + dev->size)))\n+\t\treturn true;\n+\n+\treturn false;\n+}\n+\n+static int memtrace_mmap(struct file *filp, struct vm_area_struct *vma)\n+{\n+\tunsigned long size = vma->vm_end - vma->vm_start;\n+\tstruct memtrace_entry *dev = filp->private_data;\n+\n+\tif (!valid_memtrace_range(dev, vma->vm_pgoff << PAGE_SHIFT, size))\n+\t\treturn -EINVAL;\n+\n+\tvma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);\n+\n+\tif (remap_pfn_range(vma, vma->vm_start,\n+\t\t\t       vma->vm_pgoff + (dev->start >> PAGE_SHIFT),\n+\t\t\t       size, vma->vm_page_prot))\n+\t\treturn -EAGAIN;\n+\n+\treturn 0;\n+}\n+\n+static const struct file_operations memtrace_fops = {\n+\t.llseek = default_llseek,\n+\t.read\t= memtrace_read,\n+\t.mmap\t= memtrace_mmap,\n+\t.open\t= simple_open,\n+};\n+\n+static void flush_memory_region(u64 base, u64 size)\n+{\n+\tunsigned long line_size = ppc64_caches.l1d.size;\n+\tu64 end = base + size;\n+\tu64 addr;\n+\n+\tbase = round_down(base, line_size);\n+\tend = round_up(end, line_size);\n+\n+\tfor (addr = base; addr < end; addr += line_size)\n+\t\tasm volatile(\"dcbf 0,%0\" : \"=r\" (addr) :: \"memory\");\n+}\n+\n+static int check_memblock_online(struct memory_block *mem, void *arg)\n+{\n+\tif (mem->state != MEM_ONLINE)\n+\t\treturn -1;\n+\n+\treturn 0;\n+}\n+\n+static int change_memblock_state(struct memory_block *mem, void *arg)\n+{\n+\tunsigned long state = (unsigned long)arg;\n+\n+\tmem->state = state;\n+\treturn 0;\n+}\n+\n+static bool memtrace_offline_pages(u32 nid, u64 start_pfn, u64 nr_pages)\n+{\n+\tu64 end_pfn = start_pfn + nr_pages - 1;\n+\n+\tif (walk_memory_range(start_pfn, end_pfn, NULL,\n+\t    check_memblock_online))\n+\t\treturn false;\n+\n+\twalk_memory_range(start_pfn, end_pfn, (void *)MEM_GOING_OFFLINE,\n+\t\t\t  change_memblock_state);\n+\n+\tif (offline_pages(start_pfn, nr_pages)) {\n+\t\twalk_memory_range(start_pfn, end_pfn, (void *)MEM_ONLINE,\n+\t\t\t\t  change_memblock_state);\n+\t\treturn false;\n+\t}\n+\n+\twalk_memory_range(start_pfn, end_pfn, (void *)MEM_OFFLINE,\n+\t\t\t  change_memblock_state);\n+\n+\t/* RCU grace period? */\n+\tflush_memory_region((u64)__va(start_pfn << PAGE_SHIFT),\n+\t\t\t\t\t\tnr_pages << PAGE_SHIFT);\n+\n+\tlock_device_hotplug();\n+\tremove_memory(nid, start_pfn << PAGE_SHIFT, nr_pages << PAGE_SHIFT);\n+\tunlock_device_hotplug();\n+\n+\treturn true;\n+}\n+\n+static u64 memtrace_alloc_node(u32 nid, u64 size)\n+{\n+\tu64 start_pfn, end_pfn, nr_pages;\n+\tu64 base_pfn;\n+\n+\tif (!NODE_DATA(nid) || !node_spanned_pages(nid))\n+\t\treturn 0;\n+\n+\tstart_pfn = node_start_pfn(nid);\n+\tend_pfn = node_end_pfn(nid);\n+\tnr_pages = size >> PAGE_SHIFT;\n+\n+\t/* Trace memory needs to be aligned to the size */\n+\tend_pfn = round_down(end_pfn - nr_pages, nr_pages);\n+\n+\tfor (base_pfn = end_pfn; base_pfn > start_pfn; base_pfn -= nr_pages) {\n+\t\tif (memtrace_offline_pages(nid, base_pfn, nr_pages) == true)\n+\t\t\treturn base_pfn << PAGE_SHIFT;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int memtrace_init_regions_runtime(u64 size)\n+{\n+\tu64 m;\n+\tu32 nid;\n+\n+\tmemtrace_array = kcalloc(num_online_nodes(),\n+\t\t\t\tsizeof(struct memtrace_entry), GFP_KERNEL);\n+\tif (!memtrace_array) {\n+\t\tpr_err(\"Failed to allocate memtrace_array\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tfor_each_online_node(nid) {\n+\t\tm = memtrace_alloc_node(nid, size);\n+\t\t/*\n+\t\t * A node might not have any local memory, so warn but\n+\t\t * continue on.\n+\t\t */\n+\t\tif (!m) {\n+\t\t\tpr_err(\"Failed to allocate trace memory on node %d\\n\",\n+\t\t\t\t nid);\n+\t\t} else {\n+\t\t\tpr_info(\"Allocated trace memory on node %d at \"\n+\t\t\t\t\"0x%016llx\\n\", nid, m);\n+\n+\t\t\tmemtrace_array[memtrace_array_nr].start = m;\n+\t\t\tmemtrace_array[memtrace_array_nr].size = size;\n+\t\t\tmemtrace_array[memtrace_array_nr].nid = nid;\n+\t\t\tmemtrace_array_nr++;\n+\t\t}\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static struct dentry *memtrace_debugfs_dir;\n+\n+static int memtrace_init_debugfs(void)\n+{\n+\tint ret = 0;\n+\tint i;\n+\n+\tfor (i = 0; i < memtrace_array_nr; i++) {\n+\t\tstruct dentry *dir;\n+\t\tstruct memtrace_entry *ent = &memtrace_array[i];\n+\n+\t\tent->mem = ioremap(ent->start, ent->size);\n+\t\t/* Warn but continue on */\n+\t\tif (!ent->mem) {\n+\t\t\tpr_err(\"Failed to map trace memory at 0x%llx\\n\",\n+\t\t\t\t ent->start);\n+\t\t\tret = -1;\n+\t\t\tcontinue;\n+\t\t}\n+\n+\t\tsnprintf(ent->name, 16, \"%08x\", ent->nid);\n+\t\tdir = debugfs_create_dir(ent->name, memtrace_debugfs_dir);\n+\t\tif (!dir)\n+\t\t\treturn -1;\n+\n+\t\tent->dir = dir;\n+\t\tdebugfs_create_file(\"trace\", 0400, dir, ent, &memtrace_fops);\n+\t\tdebugfs_create_x64(\"start\", 0400, dir, &ent->start);\n+\t\tdebugfs_create_x64(\"size\", 0400, dir, &ent->size);\n+\t}\n+\n+\treturn ret;\n+}\n+\n+static u64 memtrace_size;\n+\n+static int memtrace_enable_set(void *data, u64 val)\n+{\n+\tif (memtrace_size)\n+\t\treturn -EINVAL;\n+\n+\tif (!val)\n+\t\treturn -EINVAL;\n+\n+\t/* Make sure size is aligned to a memory block */\n+\tif (val & (memory_block_size_bytes() - 1))\n+\t\treturn -EINVAL;\n+\n+\tif (memtrace_init_regions_runtime(val))\n+\t\treturn -EINVAL;\n+\n+\tif (memtrace_init_debugfs())\n+\t\treturn -EINVAL;\n+\n+\tmemtrace_size = val;\n+\n+\treturn 0;\n+}\n+\n+static int memtrace_enable_get(void *data, u64 *val)\n+{\n+\t*val = memtrace_size;\n+\treturn 0;\n+}\n+\n+DEFINE_SIMPLE_ATTRIBUTE(memtrace_init_fops, memtrace_enable_get,\n+\t\t\t\t\tmemtrace_enable_set, \"0x%016llx\\n\");\n+\n+static int memtrace_init(void)\n+{\n+\tmemtrace_debugfs_dir = debugfs_create_dir(\"memtrace\",\n+\t\t\t\t\t\tpowerpc_debugfs_root);\n+\tif (!memtrace_debugfs_dir)\n+\t\treturn -1;\n+\n+\tdebugfs_create_file(\"enable\", 0600, memtrace_debugfs_dir,\n+\t\t\t    NULL, &memtrace_init_fops);\n+\n+\treturn 0;\n+}\n+machine_device_initcall(powernv, memtrace_init);\n+\n+\n+\n",
    "prefixes": [
        "v3",
        "2/3"
    ]
}