Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/806488/?format=api
{ "id": 806488, "url": "http://patchwork.ozlabs.org/api/patches/806488/?format=api", "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/patch/1503914913-28893-2-git-send-email-wei.w.wang@intel.com/", "project": { "id": 14, "url": "http://patchwork.ozlabs.org/api/projects/14/?format=api", "name": "QEMU Development", "link_name": "qemu-devel", "list_id": "qemu-devel.nongnu.org", "list_email": "qemu-devel@nongnu.org", "web_url": "", "scm_url": "", "webscm_url": "", "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<1503914913-28893-2-git-send-email-wei.w.wang@intel.com>", "list_archive_url": null, "date": "2017-08-28T10:08:29", "name": "[v15,1/5] lib/xbitmap: Introduce xbitmap", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "6448b2552407b712a037f4793de9c604ff18292e", "submitter": { "id": 69100, "url": "http://patchwork.ozlabs.org/api/people/69100/?format=api", "name": "Wang, Wei W", "email": "wei.w.wang@intel.com" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/qemu-devel/patch/1503914913-28893-2-git-send-email-wei.w.wang@intel.com/mbox/", "series": [ { "id": 126, "url": "http://patchwork.ozlabs.org/api/series/126/?format=api", "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/list/?series=126", "date": "2017-08-28T10:08:28", "name": "Virtio-balloon Enhancement", "version": 15, "mbox": "http://patchwork.ozlabs.org/series/126/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/806488/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/806488/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>", "X-Original-To": "incoming@patchwork.ozlabs.org", "Delivered-To": "patchwork-incoming@bilbo.ozlabs.org", "Authentication-Results": "ozlabs.org;\n\tspf=pass (mailfrom) smtp.mailfrom=nongnu.org\n\t(client-ip=2001:4830:134:3::11; helo=lists.gnu.org;\n\tenvelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org;\n\treceiver=<UNKNOWN>)", "Received": [ "from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11])\n\t(using TLSv1 with cipher AES256-SHA (256/256 bits))\n\t(No client certificate requested)\n\tby ozlabs.org (Postfix) with ESMTPS id 3xgnqF014mz9s8P\n\tfor <incoming@patchwork.ozlabs.org>;\n\tMon, 28 Aug 2017 20:21:12 +1000 (AEST)", "from localhost ([::1]:37850 helo=lists.gnu.org)\n\tby lists.gnu.org with esmtp (Exim 4.71) (envelope-from\n\t<qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>)\n\tid 1dmHAM-0001zs-Sn\n\tfor incoming@patchwork.ozlabs.org; Mon, 28 Aug 2017 06:21:10 -0400", "from eggs.gnu.org ([2001:4830:134:3::10]:57797)\n\tby lists.gnu.org with esmtp (Exim 4.71)\n\t(envelope-from <wei.w.wang@intel.com>) id 1dmH9j-0001xZ-6s\n\tfor qemu-devel@nongnu.org; Mon, 28 Aug 2017 06:20:33 -0400", "from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71)\n\t(envelope-from <wei.w.wang@intel.com>) id 1dmH9f-0005vE-NP\n\tfor qemu-devel@nongnu.org; Mon, 28 Aug 2017 06:20:31 -0400", "from mga04.intel.com ([192.55.52.120]:11758)\n\tby eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32)\n\t(Exim 4.71) (envelope-from <wei.w.wang@intel.com>)\n\tid 1dmH9f-0005rT-Bx\n\tfor qemu-devel@nongnu.org; Mon, 28 Aug 2017 06:20:27 -0400", "from orsmga003.jf.intel.com ([10.7.209.27])\n\tby fmsmga104.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t28 Aug 2017 03:20:26 -0700", "from devel-ww.sh.intel.com ([10.239.48.92])\n\tby orsmga003.jf.intel.com with ESMTP; 28 Aug 2017 03:20:23 -0700" ], "X-ExtLoop1": "1", "X-IronPort-AV": "E=Sophos; i=\"5.41,441,1498546800\"; d=\"scan'208\";\n\ta=\"1008318941\"", "From": "Wei Wang <wei.w.wang@intel.com>", "To": "virtio-dev@lists.oasis-open.org, linux-kernel@vger.kernel.org,\n\tqemu-devel@nongnu.org, virtualization@lists.linux-foundation.org,\n\tkvm@vger.kernel.org, linux-mm@kvack.org, mst@redhat.com,\n\tmhocko@kernel.org, akpm@linux-foundation.org, mawilcox@microsoft.com", "Date": "Mon, 28 Aug 2017 18:08:29 +0800", "Message-Id": "<1503914913-28893-2-git-send-email-wei.w.wang@intel.com>", "X-Mailer": "git-send-email 2.7.4", "In-Reply-To": "<1503914913-28893-1-git-send-email-wei.w.wang@intel.com>", "References": "<1503914913-28893-1-git-send-email-wei.w.wang@intel.com>", "X-detected-operating-system": "by eggs.gnu.org: Genre and OS details not\n\trecognized.", "X-Received-From": "192.55.52.120", "Subject": "[Qemu-devel] [PATCH v15 1/5] lib/xbitmap: Introduce xbitmap", "X-BeenThere": "qemu-devel@nongnu.org", "X-Mailman-Version": "2.1.21", "Precedence": "list", "List-Id": "<qemu-devel.nongnu.org>", "List-Unsubscribe": "<https://lists.nongnu.org/mailman/options/qemu-devel>,\n\t<mailto:qemu-devel-request@nongnu.org?subject=unsubscribe>", "List-Archive": "<http://lists.nongnu.org/archive/html/qemu-devel/>", "List-Post": "<mailto:qemu-devel@nongnu.org>", "List-Help": "<mailto:qemu-devel-request@nongnu.org?subject=help>", "List-Subscribe": "<https://lists.nongnu.org/mailman/listinfo/qemu-devel>,\n\t<mailto:qemu-devel-request@nongnu.org?subject=subscribe>", "Cc": "aarcange@redhat.com, yang.zhang.wz@gmail.com, david@redhat.com,\n\tliliang.opensource@gmail.com, willy@infradead.org,\n\tamit.shah@redhat.com, wei.w.wang@intel.com, quan.xu@aliyun.com,\n\tcornelia.huck@de.ibm.com, pbonzini@redhat.com,\n\tmgorman@techsingularity.net", "Errors-To": "qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org", "Sender": "\"Qemu-devel\"\n\t<qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>" }, "content": "From: Matthew Wilcox <mawilcox@microsoft.com>\n\nThe eXtensible Bitmap is a sparse bitmap representation which is\nefficient for set bits which tend to cluster. It supports up to\n'unsigned long' worth of bits, and this commit adds the bare bones --\nxb_set_bit(), xb_clear_bit() and xb_test_bit().\n\nSigned-off-by: Matthew Wilcox <mawilcox@microsoft.com>\nSigned-off-by: Wei Wang <wei.w.wang@intel.com>\nCc: Andrew Morton <akpm@linux-foundation.org>\nCc: Michal Hocko <mhocko@kernel.org>\nCc: Michael S. Tsirkin <mst@redhat.com>\n---\n include/linux/radix-tree.h | 3 +\n include/linux/xbitmap.h | 61 ++++++++++++++++\n lib/Makefile | 2 +-\n lib/radix-tree.c | 22 +++++-\n lib/xbitmap.c | 176 +++++++++++++++++++++++++++++++++++++++++++++\n 5 files changed, 260 insertions(+), 4 deletions(-)\n create mode 100644 include/linux/xbitmap.h\n create mode 100644 lib/xbitmap.c", "diff": "diff --git a/include/linux/radix-tree.h b/include/linux/radix-tree.h\nindex 3e57350..e1203b1 100644\n--- a/include/linux/radix-tree.h\n+++ b/include/linux/radix-tree.h\n@@ -309,6 +309,8 @@ void radix_tree_iter_replace(struct radix_tree_root *,\n \t\tconst struct radix_tree_iter *, void __rcu **slot, void *entry);\n void radix_tree_replace_slot(struct radix_tree_root *,\n \t\t\t void __rcu **slot, void *entry);\n+bool __radix_tree_delete(struct radix_tree_root *root,\n+\t\t\t struct radix_tree_node *node, void __rcu **slot);\n void __radix_tree_delete_node(struct radix_tree_root *,\n \t\t\t struct radix_tree_node *,\n \t\t\t radix_tree_update_node_t update_node,\n@@ -325,6 +327,7 @@ unsigned int radix_tree_gang_lookup(const struct radix_tree_root *,\n unsigned int radix_tree_gang_lookup_slot(const struct radix_tree_root *,\n \t\t\tvoid __rcu ***results, unsigned long *indices,\n \t\t\tunsigned long first_index, unsigned int max_items);\n+int __radix_tree_preload(gfp_t gfp_mask, unsigned int nr);\n int radix_tree_preload(gfp_t gfp_mask);\n int radix_tree_maybe_preload(gfp_t gfp_mask);\n int radix_tree_maybe_preload_order(gfp_t gfp_mask, int order);\ndiff --git a/include/linux/xbitmap.h b/include/linux/xbitmap.h\nnew file mode 100644\nindex 0000000..25b05ff\n--- /dev/null\n+++ b/include/linux/xbitmap.h\n@@ -0,0 +1,61 @@\n+/*\n+ * eXtensible Bitmaps\n+ * Copyright (c) 2017 Microsoft Corporation <mawilcox@microsoft.com>\n+ *\n+ * This program is free software; you can redistribute it and/or\n+ * modify it under the terms of the GNU General Public License as\n+ * published by the Free Software Foundation; either version 2 of the\n+ * License, or (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+ * eXtensible Bitmaps provide an unlimited-size sparse bitmap facility.\n+ * All bits are initially zero.\n+ */\n+\n+#ifndef __XBITMAP_H__\n+#define __XBITMAP_H__\n+\n+#include <linux/idr.h>\n+\n+struct xb {\n+\tstruct radix_tree_root xbrt;\n+};\n+\n+#define XB_INIT {\t\t\t\t\t\t\t\\\n+\t.xbrt = RADIX_TREE_INIT(IDR_RT_MARKER | GFP_NOWAIT),\t\t\\\n+}\n+#define DEFINE_XB(name)\t\tstruct xb name = XB_INIT\n+\n+static inline void xb_init(struct xb *xb)\n+{\n+\tINIT_RADIX_TREE(&xb->xbrt, IDR_RT_MARKER | GFP_NOWAIT);\n+}\n+\n+int xb_set_bit(struct xb *xb, unsigned long bit);\n+bool xb_test_bit(struct xb *xb, unsigned long bit);\n+void xb_clear_bit(struct xb *xb, unsigned long bit);\n+\n+/* Check if the xb tree is empty */\n+static inline bool xb_is_empty(const struct xb *xb)\n+{\n+\treturn radix_tree_empty(&xb->xbrt);\n+}\n+\n+void xb_preload(gfp_t gfp);\n+\n+/**\n+ * xb_preload_end - end preload section started with xb_preload()\n+ *\n+ * Each xb_preload() should be matched with an invocation of this\n+ * function. See xb_preload() for details.\n+ */\n+static inline void xb_preload_end(void)\n+{\n+\tpreempt_enable();\n+}\n+\n+#endif\ndiff --git a/lib/Makefile b/lib/Makefile\nindex 40c1837..ea50496 100644\n--- a/lib/Makefile\n+++ b/lib/Makefile\n@@ -18,7 +18,7 @@ KCOV_INSTRUMENT_dynamic_debug.o := n\n \n lib-y := ctype.o string.o vsprintf.o cmdline.o \\\n \t rbtree.o radix-tree.o dump_stack.o timerqueue.o\\\n-\t idr.o int_sqrt.o extable.o \\\n+\t idr.o xbitmap.o int_sqrt.o extable.o \\\n \t sha1.o chacha20.o irq_regs.o argv_split.o \\\n \t flex_proportions.o ratelimit.o show_mem.o \\\n \t is_single_threaded.o plist.o decompress.o kobject_uevent.o \\\ndiff --git a/lib/radix-tree.c b/lib/radix-tree.c\nindex 898e879..ee72e2c 100644\n--- a/lib/radix-tree.c\n+++ b/lib/radix-tree.c\n@@ -463,7 +463,7 @@ radix_tree_node_free(struct radix_tree_node *node)\n * To make use of this facility, the radix tree must be initialised without\n * __GFP_DIRECT_RECLAIM being passed to INIT_RADIX_TREE().\n */\n-static int __radix_tree_preload(gfp_t gfp_mask, unsigned nr)\n+int __radix_tree_preload(gfp_t gfp_mask, unsigned int nr)\n {\n \tstruct radix_tree_preload *rtp;\n \tstruct radix_tree_node *node;\n@@ -496,6 +496,7 @@ static int __radix_tree_preload(gfp_t gfp_mask, unsigned nr)\n out:\n \treturn ret;\n }\n+EXPORT_SYMBOL(__radix_tree_preload);\n \n /*\n * Load up this CPU's radix_tree_node buffer with sufficient objects to\n@@ -840,6 +841,8 @@ int __radix_tree_create(struct radix_tree_root *root, unsigned long index,\n \t\t\t\t\t\t\toffset, 0, 0);\n \t\t\tif (!child)\n \t\t\t\treturn -ENOMEM;\n+\t\t\tif (is_idr(root))\n+\t\t\t\tall_tag_set(child, IDR_FREE);\n \t\t\trcu_assign_pointer(*slot, node_to_entry(child));\n \t\t\tif (node)\n \t\t\t\tnode->count++;\n@@ -1986,8 +1989,20 @@ void __radix_tree_delete_node(struct radix_tree_root *root,\n \tdelete_node(root, node, update_node, private);\n }\n \n-static bool __radix_tree_delete(struct radix_tree_root *root,\n-\t\t\t\tstruct radix_tree_node *node, void __rcu **slot)\n+/**\n+ * __radix_tree_delete - delete a slot from a radix tree\n+ * @root: radix tree root\n+ * @node: node containing the slot\n+ * @slot: pointer to the slot to delete\n+ *\n+ * Clear @slot from @node of the radix tree. This may cause the current node to\n+ * be freed. This function may be called without any locking if there are no\n+ * other threads which can access this tree.\n+ *\n+ * Return: the node or NULL if the node is freed.\n+ */\n+bool __radix_tree_delete(struct radix_tree_root *root,\n+\t\t\t struct radix_tree_node *node, void __rcu **slot)\n {\n \tvoid *old = rcu_dereference_raw(*slot);\n \tint exceptional = radix_tree_exceptional_entry(old) ? -1 : 0;\n@@ -2003,6 +2018,7 @@ static bool __radix_tree_delete(struct radix_tree_root *root,\n \treplace_slot(slot, NULL, node, -1, exceptional);\n \treturn node && delete_node(root, node, NULL, NULL);\n }\n+EXPORT_SYMBOL(__radix_tree_delete);\n \n /**\n * radix_tree_iter_delete - delete the entry at this iterator position\ndiff --git a/lib/xbitmap.c b/lib/xbitmap.c\nnew file mode 100644\nindex 0000000..8c55296\n--- /dev/null\n+++ b/lib/xbitmap.c\n@@ -0,0 +1,176 @@\n+#include <linux/slab.h>\n+#include <linux/xbitmap.h>\n+\n+/*\n+ * The xbitmap implementation supports up to ULONG_MAX bits, and it is\n+ * implemented based on ida bitmaps. So, given an unsigned long index,\n+ * the high order XB_INDEX_BITS bits of the index is used to find the\n+ * corresponding item (i.e. ida bitmap) from the radix tree, and the low\n+ * order (i.e. ilog2(IDA_BITMAP_BITS)) bits of the index are indexed into\n+ * the ida bitmap to find the bit.\n+ */\n+#define XB_INDEX_BITS\t\t(BITS_PER_LONG - ilog2(IDA_BITMAP_BITS))\n+#define XB_MAX_PATH\t\t(DIV_ROUND_UP(XB_INDEX_BITS, \\\n+\t\t\t\t\t RADIX_TREE_MAP_SHIFT))\n+#define XB_PRELOAD_SIZE\t\t(XB_MAX_PATH * 2 - 1)\n+\n+enum xb_ops {\n+\tXB_SET,\n+\tXB_CLEAR,\n+\tXB_TEST\n+};\n+\n+static int xb_bit_ops(struct xb *xb, unsigned long bit, enum xb_ops ops)\n+{\n+\tint ret = 0;\n+\tunsigned long index = bit / IDA_BITMAP_BITS;\n+\tstruct radix_tree_root *root = &xb->xbrt;\n+\tstruct radix_tree_node *node;\n+\tvoid **slot;\n+\tstruct ida_bitmap *bitmap;\n+\tunsigned long ebit, tmp;\n+\n+\tbit %= IDA_BITMAP_BITS;\n+\tebit = bit + RADIX_TREE_EXCEPTIONAL_SHIFT;\n+\n+\tswitch (ops) {\n+\tcase XB_SET:\n+\t\tret = __radix_tree_create(root, index, 0, &node, &slot);\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\t\tbitmap = rcu_dereference_raw(*slot);\n+\t\tif (radix_tree_exception(bitmap)) {\n+\t\t\ttmp = (unsigned long)bitmap;\n+\t\t\tif (ebit < BITS_PER_LONG) {\n+\t\t\t\ttmp |= 1UL << ebit;\n+\t\t\t\trcu_assign_pointer(*slot, (void *)tmp);\n+\t\t\t\treturn 0;\n+\t\t\t}\n+\t\t\tbitmap = this_cpu_xchg(ida_bitmap, NULL);\n+\t\t\tif (!bitmap)\n+\t\t\t\treturn -EAGAIN;\n+\t\t\tmemset(bitmap, 0, sizeof(*bitmap));\n+\t\t\tbitmap->bitmap[0] =\n+\t\t\t\t\ttmp >> RADIX_TREE_EXCEPTIONAL_SHIFT;\n+\t\t\trcu_assign_pointer(*slot, bitmap);\n+\t\t}\n+\t\tif (!bitmap) {\n+\t\t\tif (ebit < BITS_PER_LONG) {\n+\t\t\t\tbitmap = (void *)((1UL << ebit) |\n+\t\t\t\t\tRADIX_TREE_EXCEPTIONAL_ENTRY);\n+\t\t\t\t__radix_tree_replace(root, node, slot, bitmap,\n+\t\t\t\t\t\t NULL, NULL);\n+\t\t\t\treturn 0;\n+\t\t\t}\n+\t\t\tbitmap = this_cpu_xchg(ida_bitmap, NULL);\n+\t\t\tif (!bitmap)\n+\t\t\t\treturn -EAGAIN;\n+\t\t\tmemset(bitmap, 0, sizeof(*bitmap));\n+\t\t\t__radix_tree_replace(root, node, slot, bitmap, NULL,\n+\t\t\t\t\t NULL);\n+\t\t}\n+\t\t__set_bit(bit, bitmap->bitmap);\n+\t\tbreak;\n+\tcase XB_CLEAR:\n+\t\tbitmap = __radix_tree_lookup(root, index, &node, &slot);\n+\t\tif (radix_tree_exception(bitmap)) {\n+\t\t\ttmp = (unsigned long)bitmap;\n+\t\t\tif (ebit >= BITS_PER_LONG)\n+\t\t\t\treturn 0;\n+\t\t\ttmp &= ~(1UL << ebit);\n+\t\t\tif (tmp == RADIX_TREE_EXCEPTIONAL_ENTRY)\n+\t\t\t\t__radix_tree_delete(root, node, slot);\n+\t\t\telse\n+\t\t\t\trcu_assign_pointer(*slot, (void *)tmp);\n+\t\t\treturn 0;\n+\t\t}\n+\t\tif (!bitmap)\n+\t\t\treturn 0;\n+\t\t__clear_bit(bit, bitmap->bitmap);\n+\t\tif (bitmap_empty(bitmap->bitmap, IDA_BITMAP_BITS)) {\n+\t\t\tkfree(bitmap);\n+\t\t\t__radix_tree_delete(root, node, slot);\n+\t\t}\n+\t\tbreak;\n+\tcase XB_TEST:\n+\t\tbitmap = radix_tree_lookup(root, index);\n+\t\tif (!bitmap)\n+\t\t\treturn 0;\n+\t\tif (radix_tree_exception(bitmap)) {\n+\t\t\tif (ebit > BITS_PER_LONG)\n+\t\t\t\treturn 0;\n+\t\t\treturn (unsigned long)bitmap & (1UL << bit);\n+\t\t}\n+\t\tret = test_bit(bit, bitmap->bitmap);\n+\t\tbreak;\n+\tdefault:\n+\t\treturn -EINVAL;\n+\t}\n+\treturn ret;\n+}\n+\n+/**\n+ * xb_set_bit - set a bit in the xbitmap\n+ * @xb: the xbitmap tree used to record the bit\n+ * @bit: index of the bit to set\n+ *\n+ * This function is used to set a bit in the xbitmap. If the bitmap that @bit\n+ * resides in is not there, it will be allocated.\n+ *\n+ * Returns: 0 on success. %-EAGAIN indicates that @bit was not set. The caller\n+ * may want to call the function again.\n+ */\n+int xb_set_bit(struct xb *xb, unsigned long bit)\n+{\n+\treturn xb_bit_ops(xb, bit, XB_SET);\n+}\n+EXPORT_SYMBOL(xb_set_bit);\n+\n+/**\n+ * xb_clear_bit - clear a bit in the xbitmap\n+ * @xb: the xbitmap tree used to record the bit\n+ * @bit: index of the bit to set\n+ *\n+ * This function is used to clear a bit in the xbitmap. If all the bits of the\n+ * bitmap are 0, the bitmap will be freed.\n+ */\n+void xb_clear_bit(struct xb *xb, unsigned long bit)\n+{\n+\txb_bit_ops(xb, bit, XB_CLEAR);\n+}\n+EXPORT_SYMBOL(xb_clear_bit);\n+\n+/**\n+ * xb_test_bit - test a bit in the xbitmap\n+ * @xb: the xbitmap tree used to record the bit\n+ * @bit: index of the bit to set\n+ *\n+ * This function is used to test a bit in the xbitmap.\n+ * Returns: 1 if the bit is set, or 0 otherwise.\n+ */\n+bool xb_test_bit(struct xb *xb, unsigned long bit)\n+{\n+\treturn (bool)xb_bit_ops(xb, bit, XB_TEST);\n+}\n+EXPORT_SYMBOL(xb_test_bit);\n+\n+/**\n+ * xb_preload - preload for xb_set_bit()\n+ * @gfp_mask: allocation mask to use for preloading\n+ *\n+ * Preallocate memory to use for the next call to xb_set_bit(). This function\n+ * returns with preemption disabled. It will be enabled by xb_preload_end().\n+ */\n+void xb_preload(gfp_t gfp)\n+{\n+\t__radix_tree_preload(gfp, XB_PRELOAD_SIZE);\n+\tif (!this_cpu_read(ida_bitmap)) {\n+\t\tstruct ida_bitmap *bitmap = kmalloc(sizeof(*bitmap), gfp);\n+\n+\t\tif (!bitmap)\n+\t\t\treturn;\n+\t\tbitmap = this_cpu_cmpxchg(ida_bitmap, NULL, bitmap);\n+\t\tkfree(bitmap);\n+\t}\n+}\n+EXPORT_SYMBOL(xb_preload);\n", "prefixes": [ "v15", "1/5" ] }