get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 46129,
    "url": "http://patches.dpdk.org/api/patches/46129/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1538743527-8285-2-git-send-email-alejandro.lucero@netronome.com/",
    "project": {
        "id": 1,
        "url": "http://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": "<1538743527-8285-2-git-send-email-alejandro.lucero@netronome.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1538743527-8285-2-git-send-email-alejandro.lucero@netronome.com",
    "date": "2018-10-05T12:45:22",
    "name": "[v3,1/6] mem: add function for checking memsegs IOVAs addresses",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "b7a080ad2d31fa566acbc66cc7c53ecb2d641ea7",
    "submitter": {
        "id": 270,
        "url": "http://patches.dpdk.org/api/people/270/?format=api",
        "name": "Alejandro Lucero",
        "email": "alejandro.lucero@netronome.com"
    },
    "delegate": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/users/1/?format=api",
        "username": "tmonjalo",
        "first_name": "Thomas",
        "last_name": "Monjalon",
        "email": "thomas@monjalon.net"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/1538743527-8285-2-git-send-email-alejandro.lucero@netronome.com/mbox/",
    "series": [
        {
            "id": 1717,
            "url": "http://patches.dpdk.org/api/series/1717/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=1717",
            "date": "2018-10-05T12:45:21",
            "name": "use IOVAs check based on DMA mask",
            "version": 3,
            "mbox": "http://patches.dpdk.org/series/1717/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/46129/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/46129/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 439664C8E;\n\tFri,  5 Oct 2018 14:46:54 +0200 (CEST)",
            "from netronome.com (host-79-78-33-110.static.as9105.net\n\t[79.78.33.110]) by dpdk.org (Postfix) with ESMTP id 9B3483195\n\tfor <dev@dpdk.org>; Fri,  5 Oct 2018 14:46:50 +0200 (CEST)",
            "from netronome.com (localhost [127.0.0.1])\n\tby netronome.com (8.14.4/8.14.4/Debian-4.1ubuntu1) with ESMTP id\n\tw95CjUMN008370 for <dev@dpdk.org>; Fri, 5 Oct 2018 13:45:30 +0100",
            "(from alucero@localhost)\n\tby netronome.com (8.14.4/8.14.4/Submit) id w95CjUbF008369\n\tfor dev@dpdk.org; Fri, 5 Oct 2018 13:45:30 +0100"
        ],
        "From": "Alejandro Lucero <alejandro.lucero@netronome.com>",
        "To": "dev@dpdk.org",
        "Date": "Fri,  5 Oct 2018 13:45:22 +0100",
        "Message-Id": "<1538743527-8285-2-git-send-email-alejandro.lucero@netronome.com>",
        "X-Mailer": "git-send-email 1.9.1",
        "In-Reply-To": "<1538743527-8285-1-git-send-email-alejandro.lucero@netronome.com>",
        "References": "<1538743527-8285-1-git-send-email-alejandro.lucero@netronome.com>",
        "Subject": "[dpdk-dev] [PATCH v3 1/6] mem: add function for checking memsegs\n\tIOVAs addresses",
        "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://mails.dpdk.org/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "A device can suffer addressing limitations. This function checks\nmemsegs have iovas within the supported range based on dma mask.\n\nPMDs should use this function during initialization if device\nsuffers addressing limitations, returning an error if this function\nreturns memsegs out of range.\n\nAnother usage is for emulated IOMMU hardware with addressing\nlimitations.\n\nIt is necessary to save the most restricted dma mask for checking out\nmemory allocated dynamically after initialization.\n\nSigned-off-by: Alejandro Lucero <alejandro.lucero@netronome.com>\nReviewed-by: Anatoly Burakov <anatoly.burakov@intel.com>\n---\n doc/guides/rel_notes/release_18_11.rst            | 10 ++++\n lib/librte_eal/common/eal_common_memory.c         | 60 +++++++++++++++++++++++\n lib/librte_eal/common/include/rte_eal_memconfig.h |  3 ++\n lib/librte_eal/common/include/rte_memory.h        |  3 ++\n lib/librte_eal/common/malloc_heap.c               | 12 +++++\n lib/librte_eal/linuxapp/eal/eal.c                 |  2 +\n lib/librte_eal/rte_eal_version.map                |  1 +\n 7 files changed, 91 insertions(+)",
    "diff": "diff --git a/doc/guides/rel_notes/release_18_11.rst b/doc/guides/rel_notes/release_18_11.rst\nindex 2133a5b..c806dc6 100644\n--- a/doc/guides/rel_notes/release_18_11.rst\n+++ b/doc/guides/rel_notes/release_18_11.rst\n@@ -104,6 +104,14 @@ New Features\n   the specified port. The port must be stopped before the command call in order\n   to reconfigure queues.\n \n+* **Added check for ensuring allocated memory addressable by devices.**\n+\n+  Some devices can have addressing limitations so a new function,\n+  ``rte_eal_check_dma_mask``, has been added for checking allocated memory is\n+  not out of the device range. Because now memory can be dynamically allocated\n+  after initialization, a dma mask is kept and any new allocated memory will be\n+  checked out against that dma mask and rejected if out of range. If more than\n+  one device has addressing limitations, the dma mask is the more restricted one.\n \n API Changes\n -----------\n@@ -156,6 +164,8 @@ ABI Changes\n        ``rte_config`` structure on account of improving DPDK usability when\n        using either ``--legacy-mem`` or ``--single-file-segments`` flags.\n \n+* eal: added ``dma_maskbits`` to ``rte_mem_config`` for keeping more restricted\n+       dma mask based on devices addressing limitations.\n \n Removed Items\n -------------\ndiff --git a/lib/librte_eal/common/eal_common_memory.c b/lib/librte_eal/common/eal_common_memory.c\nindex 0b69804..c482f0d 100644\n--- a/lib/librte_eal/common/eal_common_memory.c\n+++ b/lib/librte_eal/common/eal_common_memory.c\n@@ -385,6 +385,66 @@ struct virtiova {\n \trte_memseg_walk(dump_memseg, f);\n }\n \n+static int\n+check_iova(const struct rte_memseg_list *msl __rte_unused,\n+\t\tconst struct rte_memseg *ms, void *arg)\n+{\n+\tuint64_t *mask = arg;\n+\trte_iova_t iova;\n+\n+\t/* higher address within segment */\n+\tiova = (ms->iova + ms->len) - 1;\n+\tif (!(iova & *mask))\n+\t\treturn 0;\n+\n+\tRTE_LOG(DEBUG, EAL, \"memseg iova %\"PRIx64\", len %zx, out of range\\n\",\n+\t\t\t    ms->iova, ms->len);\n+\n+\tRTE_LOG(DEBUG, EAL, \"\\tusing dma mask %\"PRIx64\"\\n\", *mask);\n+\treturn 1;\n+}\n+\n+#if defined(RTE_ARCH_64)\n+#define MAX_DMA_MASK_BITS 63\n+#else\n+#define MAX_DMA_MASK_BITS 31\n+#endif\n+\n+/* check memseg iovas are within the required range based on dma mask */\n+int __rte_experimental\n+rte_eal_check_dma_mask(uint8_t maskbits)\n+{\n+\tstruct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;\n+\tuint64_t mask;\n+\n+\t/* sanity check */\n+\tif (maskbits > MAX_DMA_MASK_BITS) {\n+\t\tRTE_LOG(ERR, EAL, \"wrong dma mask size %u (Max: %u)\\n\",\n+\t\t\t\t   maskbits, MAX_DMA_MASK_BITS);\n+\t\treturn -1;\n+\t}\n+\n+\t/* create dma mask */\n+\tmask = ~((1ULL << maskbits) - 1);\n+\n+\tif (rte_memseg_walk(check_iova, &mask))\n+\t\t/*\n+\t\t * Dma mask precludes hugepage usage.\n+\t\t * This device can not be used and we do not need to keep\n+\t\t * the dma mask.\n+\t\t */\n+\t\treturn 1;\n+\n+\t/*\n+\t * we need to keep the more restricted maskbit for checking\n+\t * potential dynamic memory allocation in the future.\n+\t */\n+\tmcfg->dma_maskbits = mcfg->dma_maskbits == 0 ? maskbits :\n+\t\t\t     RTE_MIN(mcfg->dma_maskbits, maskbits);\n+\n+\treturn 0;\n+}\n+\n /* return the number of memory channels */\n unsigned rte_memory_get_nchannel(void)\n {\ndiff --git a/lib/librte_eal/common/include/rte_eal_memconfig.h b/lib/librte_eal/common/include/rte_eal_memconfig.h\nindex 62a21c2..b5dff70 100644\n--- a/lib/librte_eal/common/include/rte_eal_memconfig.h\n+++ b/lib/librte_eal/common/include/rte_eal_memconfig.h\n@@ -81,6 +81,9 @@ struct rte_mem_config {\n \t/* legacy mem and single file segments options are shared */\n \tuint32_t legacy_mem;\n \tuint32_t single_file_segments;\n+\n+\t/* keeps the more restricted dma mask */\n+\tuint8_t dma_maskbits;\n } __attribute__((__packed__));\n \n \ndiff --git a/lib/librte_eal/common/include/rte_memory.h b/lib/librte_eal/common/include/rte_memory.h\nindex 14bd277..c349d6c 100644\n--- a/lib/librte_eal/common/include/rte_memory.h\n+++ b/lib/librte_eal/common/include/rte_memory.h\n@@ -454,6 +454,9 @@ typedef int (*rte_memseg_list_walk_t)(const struct rte_memseg_list *msl,\n  */\n unsigned rte_memory_get_nrank(void);\n \n+/* check memsegs iovas are within a range based on dma mask */\n+int rte_eal_check_dma_mask(uint8_t maskbits);\n+\n /**\n  * Drivers based on uio will not load unless physical\n  * addresses are obtainable. It is only possible to get\ndiff --git a/lib/librte_eal/common/malloc_heap.c b/lib/librte_eal/common/malloc_heap.c\nindex ac7bbb3..3b5b2b6 100644\n--- a/lib/librte_eal/common/malloc_heap.c\n+++ b/lib/librte_eal/common/malloc_heap.c\n@@ -259,11 +259,13 @@ struct malloc_elem *\n \t\tint socket, unsigned int flags, size_t align, size_t bound,\n \t\tbool contig, struct rte_memseg **ms, int n_segs)\n {\n+\tstruct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;\n \tstruct rte_memseg_list *msl;\n \tstruct malloc_elem *elem = NULL;\n \tsize_t alloc_sz;\n \tint allocd_pages;\n \tvoid *ret, *map_addr;\n+\tuint64_t mask;\n \n \talloc_sz = (size_t)pg_sz * n_segs;\n \n@@ -291,6 +293,16 @@ struct malloc_elem *\n \t\tgoto fail;\n \t}\n \n+\tif (mcfg->dma_maskbits) {\n+\t\tmask = ~((1ULL << mcfg->dma_maskbits) - 1);\n+\t\tif (rte_eal_check_dma_mask(mask)) {\n+\t\t\tRTE_LOG(ERR, EAL,\n+\t\t\t\t\"%s(): couldn't allocate memory due to DMA mask\\n\",\n+\t\t\t\t__func__);\n+\t\t\tgoto fail;\n+\t\t}\n+\t}\n+\n \t/* add newly minted memsegs to malloc heap */\n \telem = malloc_heap_add_memory(heap, msl, map_addr, alloc_sz);\n \ndiff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c\nindex 4a55d3b..dfe1b8c 100644\n--- a/lib/librte_eal/linuxapp/eal/eal.c\n+++ b/lib/librte_eal/linuxapp/eal/eal.c\n@@ -263,6 +263,8 @@ enum rte_iova_mode\n \t * processes could later map the config into this exact location */\n \trte_config.mem_config->mem_cfg_addr = (uintptr_t) rte_mem_cfg_addr;\n \n+\trte_config.mem_config->dma_maskbits = 0;\n+\n }\n \n /* attach to an existing shared memory config */\ndiff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map\nindex 73282bb..2baefce 100644\n--- a/lib/librte_eal/rte_eal_version.map\n+++ b/lib/librte_eal/rte_eal_version.map\n@@ -291,6 +291,7 @@ EXPERIMENTAL {\n \trte_devargs_parsef;\n \trte_devargs_remove;\n \trte_devargs_type_count;\n+\trte_eal_check_dma_mask;\n \trte_eal_cleanup;\n \trte_eal_hotplug_add;\n \trte_eal_hotplug_remove;\n",
    "prefixes": [
        "v3",
        "1/6"
    ]
}