get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 37045,
    "url": "https://patches.dpdk.org/api/patches/37045/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/e6d6fcf634f4672c7723a80cbd72eff874fe3ea6.1522797505.git.anatoly.burakov@intel.com/",
    "project": {
        "id": 1,
        "url": "https://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<e6d6fcf634f4672c7723a80cbd72eff874fe3ea6.1522797505.git.anatoly.burakov@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/e6d6fcf634f4672c7723a80cbd72eff874fe3ea6.1522797505.git.anatoly.burakov@intel.com",
    "date": "2018-04-03T23:22:14",
    "name": "[dpdk-dev,v3,62/68] eal: add support for callbacks on memory hotplug",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "a4637718d72fc92269e9cdf143ce1ff309d35c2d",
    "submitter": {
        "id": 4,
        "url": "https://patches.dpdk.org/api/people/4/?format=api",
        "name": "Burakov, Anatoly",
        "email": "anatoly.burakov@intel.com"
    },
    "delegate": null,
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/e6d6fcf634f4672c7723a80cbd72eff874fe3ea6.1522797505.git.anatoly.burakov@intel.com/mbox/",
    "series": [],
    "comments": "https://patches.dpdk.org/api/patches/37045/comments/",
    "check": "fail",
    "checks": "https://patches.dpdk.org/api/patches/37045/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@dpdk.org",
        "Delivered-To": "patchwork@dpdk.org",
        "Received": [
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 59A081BA87;\n\tWed,  4 Apr 2018 01:24:11 +0200 (CEST)",
            "from mga12.intel.com (mga12.intel.com [192.55.52.136])\n\tby dpdk.org (Postfix) with ESMTP id 1CEA31B889\n\tfor <dev@dpdk.org>; Wed,  4 Apr 2018 01:22:36 +0200 (CEST)",
            "from fmsmga007.fm.intel.com ([10.253.24.52])\n\tby fmsmga106.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t03 Apr 2018 16:22:36 -0700",
            "from irvmail001.ir.intel.com ([163.33.26.43])\n\tby fmsmga007.fm.intel.com with ESMTP; 03 Apr 2018 16:22:32 -0700",
            "from sivswdev01.ir.intel.com (sivswdev01.ir.intel.com\n\t[10.237.217.45])\n\tby irvmail001.ir.intel.com (8.14.3/8.13.6/MailSET/Hub) with ESMTP id\n\tw33NMWa9013227; Wed, 4 Apr 2018 00:22:32 +0100",
            "from sivswdev01.ir.intel.com (localhost [127.0.0.1])\n\tby sivswdev01.ir.intel.com with ESMTP id w33NMWxu015037;\n\tWed, 4 Apr 2018 00:22:32 +0100",
            "(from aburakov@localhost)\n\tby sivswdev01.ir.intel.com with LOCAL id w33NMWaH015033;\n\tWed, 4 Apr 2018 00:22:32 +0100"
        ],
        "X-Amp-Result": "SKIPPED(no attachment in message)",
        "X-Amp-File-Uploaded": "False",
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.48,403,1517904000\"; d=\"scan'208\";a=\"29321671\"",
        "From": "Anatoly Burakov <anatoly.burakov@intel.com>",
        "To": "dev@dpdk.org",
        "Cc": "keith.wiles@intel.com, jianfeng.tan@intel.com, andras.kovacs@ericsson.com,\n\tlaszlo.vadkeri@ericsson.com, benjamin.walker@intel.com,\n\tbruce.richardson@intel.com, thomas@monjalon.net,\n\tkonstantin.ananyev@intel.com, kuralamudhan.ramakrishnan@intel.com,\n\tlouise.m.daly@intel.com, nelio.laranjeiro@6wind.com,\n\tyskoh@mellanox.com, pepperjo@japf.ch, jerin.jacob@caviumnetworks.com, \n\themant.agrawal@nxp.com, olivier.matz@6wind.com, shreyansh.jain@nxp.com,\n\tgowrishankar.m@linux.vnet.ibm.com",
        "Date": "Wed,  4 Apr 2018 00:22:14 +0100",
        "Message-Id": "<e6d6fcf634f4672c7723a80cbd72eff874fe3ea6.1522797505.git.anatoly.burakov@intel.com>",
        "X-Mailer": "git-send-email 1.7.0.7",
        "In-Reply-To": [
            "<cover.1522797505.git.anatoly.burakov@intel.com>",
            "<cover.1522797505.git.anatoly.burakov@intel.com>"
        ],
        "References": [
            "<cover.1522797505.git.anatoly.burakov@intel.com>",
            "<cover.1520428025.git.anatoly.burakov@intel.com>\n\t<cover.1522797505.git.anatoly.burakov@intel.com>"
        ],
        "Subject": "[dpdk-dev] [PATCH v3 62/68] eal: add support for callbacks on\n\tmemory hotplug",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://dpdk.org/ml/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://dpdk.org/ml/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://dpdk.org/ml/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "Each process will have its own callbacks. Callbacks will indicate\nwhether it's allocation and deallocation that's happened, and will\nalso provide start VA address and length of allocated block.\n\nSince memory hotplug isn't supported on FreeBSD and in legacy mem\nmode, it will not be possible to register them in either.\n\nSigned-off-by: Anatoly Burakov <anatoly.burakov@intel.com>\n---\n\nNotes:\n    v3:\n    - Made API experimental\n    - Compile fixes\n\n lib/librte_eal/common/eal_common_memalloc.c | 133 ++++++++++++++++++++++++++++\n lib/librte_eal/common/eal_common_memory.c   |  28 ++++++\n lib/librte_eal/common/eal_memalloc.h        |  11 +++\n lib/librte_eal/common/include/rte_memory.h  |  49 ++++++++++\n lib/librte_eal/rte_eal_version.map          |   2 +\n 5 files changed, 223 insertions(+)",
    "diff": "diff --git a/lib/librte_eal/common/eal_common_memalloc.c b/lib/librte_eal/common/eal_common_memalloc.c\nindex 607ec3f..2d2d46f 100644\n--- a/lib/librte_eal/common/eal_common_memalloc.c\n+++ b/lib/librte_eal/common/eal_common_memalloc.c\n@@ -2,16 +2,46 @@\n  * Copyright(c) 2017-2018 Intel Corporation\n  */\n \n+#include <string.h>\n+\n+#include <rte_errno.h>\n #include <rte_lcore.h>\n #include <rte_fbarray.h>\n #include <rte_memzone.h>\n #include <rte_memory.h>\n #include <rte_eal_memconfig.h>\n+#include <rte_rwlock.h>\n \n #include \"eal_private.h\"\n #include \"eal_internal_cfg.h\"\n #include \"eal_memalloc.h\"\n \n+struct mem_event_callback_entry {\n+\tTAILQ_ENTRY(mem_event_callback_entry) next;\n+\tchar name[RTE_MEM_EVENT_CALLBACK_NAME_LEN];\n+\trte_mem_event_callback_t clb;\n+};\n+\n+/** Double linked list of actions. */\n+TAILQ_HEAD(mem_event_callback_entry_list, mem_event_callback_entry);\n+\n+static struct mem_event_callback_entry_list mem_event_callback_list =\n+\tTAILQ_HEAD_INITIALIZER(mem_event_callback_list);\n+\n+static rte_rwlock_t mem_event_rwlock = RTE_RWLOCK_INITIALIZER;\n+\n+static struct mem_event_callback_entry *\n+find_mem_event_callback(const char *name)\n+{\n+\tstruct mem_event_callback_entry *r;\n+\n+\tTAILQ_FOREACH(r, &mem_event_callback_list, next) {\n+\t\tif (!strcmp(r->name, name))\n+\t\t\tbreak;\n+\t}\n+\treturn r;\n+}\n+\n bool\n eal_memalloc_is_contig(const struct rte_memseg_list *msl, void *start,\n \t\tsize_t len)\n@@ -88,3 +118,106 @@ eal_memalloc_is_contig(const struct rte_memseg_list *msl, void *start,\n \t}\n \treturn true;\n }\n+\n+int\n+eal_memalloc_mem_event_callback_register(const char *name,\n+\t\trte_mem_event_callback_t clb)\n+{\n+\tstruct mem_event_callback_entry *entry;\n+\tint ret, len;\n+\tif (name == NULL || clb == NULL) {\n+\t\trte_errno = EINVAL;\n+\t\treturn -1;\n+\t}\n+\tlen = strnlen(name, RTE_MEM_EVENT_CALLBACK_NAME_LEN);\n+\tif (len == 0) {\n+\t\trte_errno = EINVAL;\n+\t\treturn -1;\n+\t} else if (len == RTE_MEM_EVENT_CALLBACK_NAME_LEN) {\n+\t\trte_errno = ENAMETOOLONG;\n+\t\treturn -1;\n+\t}\n+\trte_rwlock_write_lock(&mem_event_rwlock);\n+\n+\tentry = find_mem_event_callback(name);\n+\tif (entry != NULL) {\n+\t\trte_errno = EEXIST;\n+\t\tret = -1;\n+\t\tgoto unlock;\n+\t}\n+\n+\tentry = malloc(sizeof(*entry));\n+\tif (entry == NULL) {\n+\t\trte_errno = ENOMEM;\n+\t\tret = -1;\n+\t\tgoto unlock;\n+\t}\n+\n+\t/* callback successfully created and is valid, add it to the list */\n+\tentry->clb = clb;\n+\tsnprintf(entry->name, RTE_MEM_EVENT_CALLBACK_NAME_LEN, \"%s\", name);\n+\tTAILQ_INSERT_TAIL(&mem_event_callback_list, entry, next);\n+\n+\tret = 0;\n+\n+\tRTE_LOG(DEBUG, EAL, \"Mem event callback '%s' registered\\n\", name);\n+\n+unlock:\n+\trte_rwlock_write_unlock(&mem_event_rwlock);\n+\treturn ret;\n+}\n+\n+int\n+eal_memalloc_mem_event_callback_unregister(const char *name)\n+{\n+\tstruct mem_event_callback_entry *entry;\n+\tint ret, len;\n+\n+\tif (name == NULL) {\n+\t\trte_errno = EINVAL;\n+\t\treturn -1;\n+\t}\n+\tlen = strnlen(name, RTE_MEM_EVENT_CALLBACK_NAME_LEN);\n+\tif (len == 0) {\n+\t\trte_errno = EINVAL;\n+\t\treturn -1;\n+\t} else if (len == RTE_MEM_EVENT_CALLBACK_NAME_LEN) {\n+\t\trte_errno = ENAMETOOLONG;\n+\t\treturn -1;\n+\t}\n+\trte_rwlock_write_lock(&mem_event_rwlock);\n+\n+\tentry = find_mem_event_callback(name);\n+\tif (entry == NULL) {\n+\t\trte_errno = ENOENT;\n+\t\tret = -1;\n+\t\tgoto unlock;\n+\t}\n+\tTAILQ_REMOVE(&mem_event_callback_list, entry, next);\n+\tfree(entry);\n+\n+\tret = 0;\n+\n+\tRTE_LOG(DEBUG, EAL, \"Mem event callback '%s' unregistered\\n\", name);\n+\n+unlock:\n+\trte_rwlock_write_unlock(&mem_event_rwlock);\n+\treturn ret;\n+}\n+\n+void\n+eal_memalloc_mem_event_notify(enum rte_mem_event event, const void *start,\n+\t\tsize_t len)\n+{\n+\tstruct mem_event_callback_entry *entry;\n+\n+\trte_rwlock_read_lock(&mem_event_rwlock);\n+\n+\tTAILQ_FOREACH(entry, &mem_event_callback_list, next) {\n+\t\tRTE_LOG(DEBUG, EAL, \"Calling mem event callback %s\",\n+\t\t\tentry->name);\n+\t\tentry->clb(event, start, len);\n+\t}\n+\n+\trte_rwlock_read_unlock(&mem_event_rwlock);\n+}\ndiff --git a/lib/librte_eal/common/eal_common_memory.c b/lib/librte_eal/common/eal_common_memory.c\nindex 0c4c1f5..e3ce69c 100644\n--- a/lib/librte_eal/common/eal_common_memory.c\n+++ b/lib/librte_eal/common/eal_common_memory.c\n@@ -604,6 +604,34 @@ dump_memseg(const struct rte_memseg_list *msl, const struct rte_memseg *ms,\n \treturn 0;\n }\n \n+/*\n+ * Defining here because declared in rte_memory.h, but the actual implementation\n+ * is in eal_common_memalloc.c, like all other memalloc internals.\n+ */\n+int __rte_experimental\n+rte_mem_event_callback_register(const char *name, rte_mem_event_callback_t clb)\n+{\n+\t/* FreeBSD boots with legacy mem enabled by default */\n+\tif (internal_config.legacy_mem) {\n+\t\tRTE_LOG(DEBUG, EAL, \"Registering mem event callbacks not supported\\n\");\n+\t\trte_errno = ENOTSUP;\n+\t\treturn -1;\n+\t}\n+\treturn eal_memalloc_mem_event_callback_register(name, clb);\n+}\n+\n+int __rte_experimental\n+rte_mem_event_callback_unregister(const char *name)\n+{\n+\t/* FreeBSD boots with legacy mem enabled by default */\n+\tif (internal_config.legacy_mem) {\n+\t\tRTE_LOG(DEBUG, EAL, \"Registering mem event callbacks not supported\\n\");\n+\t\trte_errno = ENOTSUP;\n+\t\treturn -1;\n+\t}\n+\treturn eal_memalloc_mem_event_callback_unregister(name);\n+}\n+\n /* Dump the physical memory layout on console */\n void\n rte_dump_physmem_layout(FILE *f)\ndiff --git a/lib/librte_eal/common/eal_memalloc.h b/lib/librte_eal/common/eal_memalloc.h\nindex 4a7b45c..4d27403 100644\n--- a/lib/librte_eal/common/eal_memalloc.h\n+++ b/lib/librte_eal/common/eal_memalloc.h\n@@ -56,4 +56,15 @@ eal_memalloc_is_contig(const struct rte_memseg_list *msl, void *start,\n int\n eal_memalloc_sync_with_primary(void);\n \n+int\n+eal_memalloc_mem_event_callback_register(const char *name,\n+\t\trte_mem_event_callback_t clb);\n+\n+int\n+eal_memalloc_mem_event_callback_unregister(const char *name);\n+\n+void\n+eal_memalloc_mem_event_notify(enum rte_mem_event event, const void *start,\n+\t\tsize_t len);\n+\n #endif // EAL_MEMALLOC_H\ndiff --git a/lib/librte_eal/common/include/rte_memory.h b/lib/librte_eal/common/include/rte_memory.h\nindex 55383c4..0de1198 100644\n--- a/lib/librte_eal/common/include/rte_memory.h\n+++ b/lib/librte_eal/common/include/rte_memory.h\n@@ -290,6 +290,55 @@ unsigned rte_memory_get_nrank(void);\n  */\n int rte_eal_using_phys_addrs(void);\n \n+\n+/**\n+ * Enum indicating which kind of memory event has happened. Used by callbacks to\n+ * distinguish between memory allocations and deallocations.\n+ */\n+enum rte_mem_event {\n+\tRTE_MEM_EVENT_ALLOC = 0, /**< Allocation event. */\n+\tRTE_MEM_EVENT_FREE,      /**< Deallocation event. */\n+};\n+#define RTE_MEM_EVENT_CALLBACK_NAME_LEN 64\n+/**< maximum length of callback name */\n+\n+/**\n+ * Function typedef used to register callbacks for memory events.\n+ */\n+typedef void (*rte_mem_event_callback_t)(enum rte_mem_event event_type,\n+\t\tconst void *addr, size_t len);\n+\n+/**\n+ * Function used to register callbacks for memory events.\n+ *\n+ * @param name\n+ *   Name associated with specified callback to be added to the list.\n+ *\n+ * @param clb\n+ *   Callback function pointer.\n+ *\n+ * @return\n+ *   0 on successful callback register\n+ *   -1 on unsuccessful callback register, with rte_errno value indicating\n+ *   reason for failure.\n+ */\n+int __rte_experimental\n+rte_mem_event_callback_register(const char *name, rte_mem_event_callback_t clb);\n+\n+/**\n+ * Function used to unregister callbacks for memory events.\n+ *\n+ * @param name\n+ *   Name associated with specified callback to be removed from the list.\n+ *\n+ * @return\n+ *   0 on successful callback unregister\n+ *   -1 on unsuccessful callback unregister, with rte_errno value indicating\n+ *   reason for failure.\n+ */\n+int __rte_experimental\n+rte_mem_event_callback_unregister(const char *name);\n+\n #ifdef __cplusplus\n }\n #endif\ndiff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map\nindex df5802d..0460edb 100644\n--- a/lib/librte_eal/rte_eal_version.map\n+++ b/lib/librte_eal/rte_eal_version.map\n@@ -238,6 +238,8 @@ EXPERIMENTAL {\n \trte_fbarray_set_used;\n \trte_log_register_type_and_pick_level;\n \trte_malloc_dump_heaps;\n+\trte_mem_event_callback_register;\n+\trte_mem_event_callback_unregister;\n \trte_mem_iova2virt;\n \trte_mem_virt2memseg;\n \trte_mem_virt2memseg_list;\n",
    "prefixes": [
        "dpdk-dev",
        "v3",
        "62/68"
    ]
}