Show a patch.

GET /api/patches/44848/
Content-Type: application/json
Vary: Accept

    "id": 44848,
    "url": "",
    "web_url": "",
    "project": {
        "id": 1,
        "url": "",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "",
        "list_email": "",
        "web_url": "",
        "scm_url": "git://",
        "webscm_url": ""
    "msgid": "<>",
    "date": "2018-09-18T13:31:49",
    "name": "[v2,06/13] bus/dpaa: add interrupt based portal fd support",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "ac7921daa09d312e48b117204965cd2fa20144f4",
    "submitter": {
        "id": 477,
        "url": "",
        "name": "Hemant Agrawal",
        "email": ""
    "delegate": {
        "id": 319,
        "url": "",
        "username": "fyigit",
        "first_name": "Ferruh",
        "last_name": "Yigit",
        "email": ""
    "mbox": "",
    "series": [
            "id": 1371,
            "url": "",
            "web_url": "",
            "date": "2018-09-18T13:31:43",
            "name": "NXP DPAA driver enhancements",
            "version": 2,
            "mbox": ""
    "comments": "",
    "check": "success",
    "checks": "",
    "tags": {},
    "headers": {
        "X-Mailman-Version": "2.1.15",
        "In-Reply-To": "<>",
        "Errors-To": "",
        "X-Mailer": "git-send-email 2.7.4",
        "Received": [
            "from [] (localhost [])\n\tby (Postfix) with ESMTP id 74B795398;\n\tTue, 18 Sep 2018 15:34:09 +0200 (CEST)",
            "from ( [])\n\tby (Postfix) with ESMTP id 474D74CA6\n\tfor <>; Tue, 18 Sep 2018 15:34:03 +0200 (CEST)",
            "from (localhost [])\n\tby (Postfix) with ESMTP id 2C19D1A0152;\n\tTue, 18 Sep 2018 15:34:03 +0200 (CEST)",
            "from (\n\t[])\n\tby (Postfix) with ESMTP id CD0541A013C;\n\tTue, 18 Sep 2018 15:34:00 +0200 (CEST)",
            "from (\n\t[])\n\tby (Postfix) with ESMTP id C891640305;\n\tTue, 18 Sep 2018 21:33:56 +0800 (SGT)"
        "References": "<>\n\t<>",
        "Delivered-To": "",
        "X-BeenThere": "",
        "Message-Id": "<>",
        "X-Virus-Scanned": "ClamAV using ClamSMTP",
        "List-Post": "<>",
        "Precedence": "list",
        "From": "Hemant Agrawal <>",
        "X-Original-To": "",
        "Return-Path": "<>",
        "Sender": "\"dev\" <>",
        "List-Help": "<>",
        "List-Subscribe": "<>,\n\t<>",
        "To": ",\n\,\n\",
        "List-Id": "DPDK patches and discussions <>",
        "List-Unsubscribe": "<>,\n\t<>",
        "Date": "Tue, 18 Sep 2018 19:01:49 +0530",
        "List-Archive": "<>",
        "Subject": "[dpdk-dev] [PATCH v2 06/13] bus/dpaa: add interrupt based portal fd\n\tsupport"
    "content": "This patch add supports in bus driver for qbman to support\nand configure portal based FDs, which can be used for interrupt\nbased processing.\n\nSigned-off-by: Hemant Agrawal <>\n---\n drivers/bus/dpaa/base/qbman/bman_driver.c | 17 ++++++----\n drivers/bus/dpaa/base/qbman/qman.c        | 52 +++++++++++++++++++++++++++++++\n drivers/bus/dpaa/base/qbman/qman_driver.c |  7 ++++-\n drivers/bus/dpaa/include/fsl_qman.h       | 20 ++++++++++++\n drivers/bus/dpaa/include/fsl_usd.h        |  6 ++++\n drivers/bus/dpaa/ | 16 +++++++++-\n 6 files changed, 110 insertions(+), 8 deletions(-)",
    "diff": "diff --git a/drivers/bus/dpaa/base/qbman/bman_driver.c b/drivers/bus/dpaa/base/qbman/bman_driver.c\nindex b14b590..750b756 100644\n--- a/drivers/bus/dpaa/base/qbman/bman_driver.c\n+++ b/drivers/bus/dpaa/base/qbman/bman_driver.c\n@@ -23,7 +23,7 @@ static void *bman_ccsr_map;\n /* Portal driver */\n /*****************/\n \n-static __thread int fd = -1;\n+static __thread int bmfd = -1;\n static __thread struct bm_portal_config pcfg;\n static __thread struct dpaa_ioctl_portal_map map = {\n \t.type = dpaa_portal_bman\n@@ -70,14 +70,14 @@ static int fsl_bman_portal_init(uint32_t idx, int is_shared)\n \tpcfg.index = map.index;\n \tbman_depletion_fill(&pcfg.mask);\n \n-\tfd = open(BMAN_PORTAL_IRQ_PATH, O_RDONLY);\n-\tif (fd == -1) {\n+\tbmfd = open(BMAN_PORTAL_IRQ_PATH, O_RDONLY);\n+\tif (bmfd == -1) {\n \t\tpr_err(\"BMan irq init failed\");\n \t\tprocess_portal_unmap(&map.addr);\n \t\treturn -EBUSY;\n \t}\n \t/* Use the IRQ FD as a unique IRQ number */\n-\tpcfg.irq = fd;\n+\tpcfg.irq = bmfd;\n \n \tportal = bman_create_affine_portal(&pcfg);\n \tif (!portal) {\n@@ -90,7 +90,7 @@ static int fsl_bman_portal_init(uint32_t idx, int is_shared)\n \t/* Set the IRQ number */\n \tirq_map.type = dpaa_portal_bman;\n \tirq_map.portal_cinh = map.addr.cinh;\n-\tprocess_portal_irq_map(fd, &irq_map);\n+\tprocess_portal_irq_map(bmfd, &irq_map);\n \treturn 0;\n }\n \n@@ -99,7 +99,7 @@ static int fsl_bman_portal_finish(void)\n \t__maybe_unused const struct bm_portal_config *cfg;\n \tint ret;\n \n-\tprocess_portal_irq_unmap(fd);\n+\tprocess_portal_irq_unmap(bmfd);\n \n \tcfg = bman_destroy_affine_portal();\n \tDPAA_BUG_ON(cfg != &pcfg);\n@@ -109,6 +109,11 @@ static int fsl_bman_portal_finish(void)\n \treturn ret;\n }\n \n+int bman_thread_fd(void)\n+{\n+\treturn bmfd;\n+}\n+\n int bman_thread_init(void)\n {\n \t/* Convert from contiguous/virtual cpu numbering to real cpu when\ndiff --git a/drivers/bus/dpaa/base/qbman/qman.c b/drivers/bus/dpaa/base/qbman/qman.c\nindex 7c17027..8730550 100644\n--- a/drivers/bus/dpaa/base/qbman/qman.c\n+++ b/drivers/bus/dpaa/base/qbman/qman.c\n@@ -1040,6 +1040,50 @@ static inline unsigned int __poll_portal_fast(struct qman_portal *p,\n \treturn limit;\n }\n \n+int qman_irqsource_add(u32 bits)\n+{\n+\tstruct qman_portal *p = get_affine_portal();\n+\n+\tbits = bits & QM_PIRQ_VISIBLE;\n+\n+\t/* Clear any previously remaining interrupt conditions in\n+\t * QCSP_ISR. This prevents raising a false interrupt when\n+\t * interrupt conditions are enabled in QCSP_IER.\n+\t */\n+\tqm_isr_status_clear(&p->p, bits);\n+\tdpaa_set_bits(bits, &p->irq_sources);\n+\tqm_isr_enable_write(&p->p, p->irq_sources);\n+\n+\n+\treturn 0;\n+}\n+\n+int qman_irqsource_remove(u32 bits)\n+{\n+\tstruct qman_portal *p = get_affine_portal();\n+\tu32 ier;\n+\n+\t/* Our interrupt handler only processes+clears status register bits that\n+\t * are in p->irq_sources. As we're trimming that mask, if one of them\n+\t * were to assert in the status register just before we remove it from\n+\t * the enable register, there would be an interrupt-storm when we\n+\t * release the IRQ lock. So we wait for the enable register update to\n+\t * take effect in h/w (by reading it back) and then clear all other bits\n+\t * in the status register. Ie. we clear them from ISR once it's certain\n+\t * IER won't allow them to reassert.\n+\t */\n+\n+\tbits &= QM_PIRQ_VISIBLE;\n+\tdpaa_clear_bits(bits, &p->irq_sources);\n+\tqm_isr_enable_write(&p->p, p->irq_sources);\n+\tier = qm_isr_enable_read(&p->p);\n+\t/* Using \"~ier\" (rather than \"bits\" or \"~p->irq_sources\") creates a\n+\t * data-dependency, ie. to protect against re-ordering.\n+\t */\n+\tqm_isr_status_clear(&p->p, ~ier);\n+\treturn 0;\n+}\n+\n u16 qman_affine_channel(int cpu)\n {\n \tif (cpu < 0) {\n@@ -1114,6 +1158,14 @@ unsigned int qman_portal_poll_rx(unsigned int poll_limit,\n \treturn rx_number;\n }\n \n+void qman_clear_irq(void)\n+{\n+\tstruct qman_portal *p = get_affine_portal();\n+\tu32 clear = QM_DQAVAIL_MASK | (p->irq_sources &\n+\t\t~(QM_PIRQ_CSCI | QM_PIRQ_CCSCI));\n+\tqm_isr_status_clear(&p->p, clear);\n+}\n+\n u32 qman_portal_dequeue(struct rte_event ev[], unsigned int poll_limit,\n \t\t\tvoid **bufs)\n {\ndiff --git a/drivers/bus/dpaa/base/qbman/qman_driver.c b/drivers/bus/dpaa/base/qbman/qman_driver.c\nindex f6ecd6b..ba15339 100644\n--- a/drivers/bus/dpaa/base/qbman/qman_driver.c\n+++ b/drivers/bus/dpaa/base/qbman/qman_driver.c\n@@ -113,6 +113,11 @@ static int fsl_qman_portal_finish(void)\n \treturn ret;\n }\n \n+int qman_thread_fd(void)\n+{\n+\treturn qmfd;\n+}\n+\n int qman_thread_init(void)\n {\n \t/* Convert from contiguous/virtual cpu numbering to real cpu when\n@@ -135,7 +140,7 @@ void qman_thread_irq(void)\n \t * rather than breaking that encapsulation I am simply hard-coding the\n \t * offset to the inhibit register here.\n \t */\n-\tout_be32(qpcfg.addr_virt[DPAA_PORTAL_CI] + 0xe0c, 0);\n+\tout_be32(qpcfg.addr_virt[DPAA_PORTAL_CI] + 0x36C0, 0);\n }\n \n struct qman_portal *fsl_qman_portal_create(void)\ndiff --git a/drivers/bus/dpaa/include/fsl_qman.h b/drivers/bus/dpaa/include/fsl_qman.h\nindex b18cf03..e438414 100644\n--- a/drivers/bus/dpaa/include/fsl_qman.h\n+++ b/drivers/bus/dpaa/include/fsl_qman.h\n@@ -1316,6 +1316,26 @@ u32 qman_portal_dequeue(struct rte_event ev[], unsigned int poll_limit,\n \t\t\tvoid **bufs);\n \n /**\n+ * qman_irqsource_add - add processing sources to be interrupt-driven\n+ * @bits: bitmask of QM_PIRQ_**I processing sources\n+ *\n+ * Adds processing sources that should be interrupt-driven (rather than\n+ * processed via qman_poll_***() functions). Returns zero for success, or\n+ * -EINVAL if the current CPU is sharing a portal hosted on another CPU.\n+ */\n+int qman_irqsource_add(u32 bits);\n+\n+/**\n+ * qman_irqsource_remove - remove processing sources from being interrupt-driven\n+ * @bits: bitmask of QM_PIRQ_**I processing sources\n+ *\n+ * Removes processing sources from being interrupt-driven, so that they will\n+ * instead be processed via qman_poll_***() functions. Returns zero for success,\n+ * or -EINVAL if the current CPU is sharing a portal hosted on another CPU.\n+ */\n+int qman_irqsource_remove(u32 bits);\n+\n+/**\n  * qman_affine_channel - return the channel ID of an portal\n  * @cpu: the cpu whose affine portal is the subject of the query\n  *\ndiff --git a/drivers/bus/dpaa/include/fsl_usd.h b/drivers/bus/dpaa/include/fsl_usd.h\nindex e183617..ec1ab7c 100644\n--- a/drivers/bus/dpaa/include/fsl_usd.h\n+++ b/drivers/bus/dpaa/include/fsl_usd.h\n@@ -55,6 +55,10 @@ int qman_free_raw_portal(struct dpaa_raw_portal *portal);\n int bman_allocate_raw_portal(struct dpaa_raw_portal *portal);\n int bman_free_raw_portal(struct dpaa_raw_portal *portal);\n \n+/* Obtain thread-local UIO file-descriptors */\n+int qman_thread_fd(void);\n+int bman_thread_fd(void);\n+\n /* Post-process interrupts. NB, the kernel IRQ handler disables the interrupt\n  * line before notifying us, and this post-processing re-enables it once\n  * processing is complete. As such, it is essential to call this before going\n@@ -63,6 +67,8 @@ int bman_free_raw_portal(struct dpaa_raw_portal *portal);\n void qman_thread_irq(void);\n void bman_thread_irq(void);\n \n+void qman_clear_irq(void);\n+\n /* Global setup */\n int qman_global_init(void);\n int bman_global_init(void);\ndiff --git a/drivers/bus/dpaa/ b/drivers/bus/dpaa/\nindex 7d6d624..70076c7 100644\n--- a/drivers/bus/dpaa/\n+++ b/drivers/bus/dpaa/\n@@ -95,10 +95,24 @@ DPDK_18.02 {\n \n DPDK_18.08 {\n \tglobal:\n-\n \tfman_if_get_sg_enable;\n \tfman_if_set_sg;\n \tof_get_mac_address;\n \n \tlocal: *;\n } DPDK_18.02;\n+\n+DPDK_18.11 {\n+\tglobal:\n+\tbman_thread_irq;\n+\tfman_if_get_sg_enable;\n+\tfman_if_set_sg;\n+\tqman_clear_irq;\n+\n+\tqman_irqsource_add;\n+\tqman_irqsource_remove;\n+\tqman_thread_fd;\n+\tqman_thread_irq;\n+\n+\tlocal: *;\n+} DPDK_18.08;\n",
    "prefixes": [