get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 139212,
    "url": "http://patches.dpdk.org/api/patches/139212/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20240409114845.1336403-4-maxime.coquelin@redhat.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": "<20240409114845.1336403-4-maxime.coquelin@redhat.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20240409114845.1336403-4-maxime.coquelin@redhat.com",
    "date": "2024-04-09T11:48:43",
    "name": "[v3,3/5] vhost: hide synchronization within FD manager",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "804c5a6dd0fde80d87dde0f5d0d1a7c6d641b380",
    "submitter": {
        "id": 512,
        "url": "http://patches.dpdk.org/api/people/512/?format=api",
        "name": "Maxime Coquelin",
        "email": "maxime.coquelin@redhat.com"
    },
    "delegate": {
        "id": 2642,
        "url": "http://patches.dpdk.org/api/users/2642/?format=api",
        "username": "mcoquelin",
        "first_name": "Maxime",
        "last_name": "Coquelin",
        "email": "maxime.coquelin@redhat.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/20240409114845.1336403-4-maxime.coquelin@redhat.com/mbox/",
    "series": [
        {
            "id": 31711,
            "url": "http://patches.dpdk.org/api/series/31711/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=31711",
            "date": "2024-04-09T11:48:40",
            "name": "vhost: FD manager improvements",
            "version": 3,
            "mbox": "http://patches.dpdk.org/series/31711/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/139212/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/139212/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "Received": [
            "from mails.dpdk.org (mails.dpdk.org [217.70.189.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 1841D43E29;\n\tTue,  9 Apr 2024 13:49:17 +0200 (CEST)",
            "from mails.dpdk.org (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id D0DA640687;\n\tTue,  9 Apr 2024 13:49:03 +0200 (CEST)",
            "from us-smtp-delivery-124.mimecast.com\n (us-smtp-delivery-124.mimecast.com [170.10.133.124])\n by mails.dpdk.org (Postfix) with ESMTP id E9E4D4067A\n for <dev@dpdk.org>; Tue,  9 Apr 2024 13:49:01 +0200 (CEST)",
            "from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com\n [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS\n (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id\n us-mta-250-I5J470SpOAmbGZrgr7vp2Q-1; Tue, 09 Apr 2024 07:48:58 -0400",
            "from smtp.corp.redhat.com (int-mx03.intmail.prod.int.rdu2.redhat.com\n [10.11.54.3])\n (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest\n SHA256)\n (No client certificate requested)\n by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 438291807B21;\n Tue,  9 Apr 2024 11:48:58 +0000 (UTC)",
            "from max-p1.redhat.com (unknown [10.39.208.27])\n by smtp.corp.redhat.com (Postfix) with ESMTP id D05D61121313;\n Tue,  9 Apr 2024 11:48:56 +0000 (UTC)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n s=mimecast20190719; t=1712663341;\n h=from:from:reply-to:subject:subject:date:date:message-id:message-id:\n to:to:cc:cc:mime-version:mime-version:content-type:content-type:\n content-transfer-encoding:content-transfer-encoding:\n in-reply-to:in-reply-to:references:references;\n bh=YdFrpBMSMdfeRz/XoGUo/0jwsXgMNyn74BVxvZwoM+Y=;\n b=A+uFzYqjgLaUjt2QdQ108NXAbdtNkwwmRCJaXfBEb1YG2rG9Ry0gb6n9b/bkUMKhh5ff4p\n 2dDIlSlCDPrxZvbivmt1MdxuCirhq+X6QOY04Mvru6OZKBHzgU/IySkJyOiRPzv8jnQQQt\n FcPUKC1PYONIqMNx9AECwo1K+8+2Xqo=",
        "X-MC-Unique": "I5J470SpOAmbGZrgr7vp2Q-1",
        "From": "Maxime Coquelin <maxime.coquelin@redhat.com>",
        "To": "dev@dpdk.org,\n\tdavid.marchand@redhat.com,\n\tchenbox@nvidia.com",
        "Cc": "Maxime Coquelin <maxime.coquelin@redhat.com>",
        "Subject": "[PATCH v3 3/5] vhost: hide synchronization within FD manager",
        "Date": "Tue,  9 Apr 2024 13:48:43 +0200",
        "Message-ID": "<20240409114845.1336403-4-maxime.coquelin@redhat.com>",
        "In-Reply-To": "<20240409114845.1336403-1-maxime.coquelin@redhat.com>",
        "References": "<20240409114845.1336403-1-maxime.coquelin@redhat.com>",
        "MIME-Version": "1.0",
        "X-Scanned-By": "MIMEDefang 3.4.1 on 10.11.54.3",
        "X-Mimecast-Spam-Score": "0",
        "X-Mimecast-Originator": "redhat.com",
        "Content-Transfer-Encoding": "8bit",
        "Content-Type": "text/plain; charset=\"US-ASCII\"; x-default=true",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.29",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <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 <mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org"
    },
    "content": "This patch forces synchronization for all FDs additions\nor deletions in the FD set. With that, it is no more\nnecessary for the user to know about the FD set pipe, so\nhide its initialization in the FD manager.\n\nSigned-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>\n---\n lib/vhost/fd_man.c | 180 ++++++++++++++++++++++++---------------------\n lib/vhost/fd_man.h |   8 +-\n lib/vhost/socket.c |  12 +--\n lib/vhost/vduse.c  |  18 +----\n 4 files changed, 101 insertions(+), 117 deletions(-)",
    "diff": "diff --git a/lib/vhost/fd_man.c b/lib/vhost/fd_man.c\nindex e42c491fdb..0ae481b785 100644\n--- a/lib/vhost/fd_man.c\n+++ b/lib/vhost/fd_man.c\n@@ -2,7 +2,9 @@\n  * Copyright(c) 2010-2014 Intel Corporation\n  */\n \n+#include <errno.h>\n #include <stdio.h>\n+#include <string.h>\n #include <unistd.h>\n \n #include <rte_common.h>\n@@ -17,6 +19,87 @@ RTE_LOG_REGISTER_SUFFIX(vhost_fdset_logtype, fdset, INFO);\n \n #define FDPOLLERR (POLLERR | POLLHUP | POLLNVAL)\n \n+static void\n+fdset_pipe_read_cb(int readfd, void *dat,\n+\t\t   int *remove __rte_unused)\n+{\n+\tchar charbuf[16];\n+\tstruct fdset *fdset = dat;\n+\tint r = read(readfd, charbuf, sizeof(charbuf));\n+\t/*\n+\t * Just an optimization, we don't care if read() failed\n+\t * so ignore explicitly its return value to make the\n+\t * compiler happy\n+\t */\n+\tRTE_SET_USED(r);\n+\n+\tpthread_mutex_lock(&fdset->sync_mutex);\n+\tfdset->sync = true;\n+\tpthread_cond_broadcast(&fdset->sync_cond);\n+\tpthread_mutex_unlock(&fdset->sync_mutex);\n+}\n+\n+static void\n+fdset_pipe_uninit(struct fdset *fdset)\n+{\n+\tfdset_del(fdset, fdset->u.readfd);\n+\tclose(fdset->u.readfd);\n+\tfdset->u.readfd = -1;\n+\tclose(fdset->u.writefd);\n+\tfdset->u.writefd = -1;\n+}\n+\n+static int\n+fdset_pipe_init(struct fdset *fdset)\n+{\n+\tint ret;\n+\n+\tpthread_mutex_init(&fdset->sync_mutex, NULL);\n+\tpthread_cond_init(&fdset->sync_cond, NULL);\n+\n+\tif (pipe(fdset->u.pipefd) < 0) {\n+\t\tVHOST_FDMAN_LOG(ERR,\n+\t\t\t\"failed to create pipe for vhost fdset\");\n+\t\treturn -1;\n+\t}\n+\n+\tret = fdset_add(fdset, fdset->u.readfd,\n+\t\t\tfdset_pipe_read_cb, NULL, fdset);\n+\tif (ret < 0) {\n+\t\tVHOST_FDMAN_LOG(ERR,\n+\t\t\t\"failed to add pipe readfd %d into vhost server fdset\",\n+\t\t\tfdset->u.readfd);\n+\n+\t\tfdset_pipe_uninit(fdset);\n+\t\treturn -1;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static void\n+fdset_sync(struct fdset *fdset)\n+{\n+\tint ret;\n+\n+\tpthread_mutex_lock(&fdset->sync_mutex);\n+\n+\tfdset->sync = false;\n+\tret = write(fdset->u.writefd, \"1\", 1);\n+\tif (ret < 0) {\n+\t\tVHOST_FDMAN_LOG(ERR,\n+\t\t\t\"Failed to write to notification pipe: %s\",\n+\t\t\tstrerror(errno));\n+\t\tgoto out_unlock;\n+\t}\n+\n+\twhile (!fdset->sync)\n+\t\tpthread_cond_wait(&fdset->sync_cond, &fdset->sync_mutex);\n+\n+out_unlock:\n+\tpthread_mutex_unlock(&fdset->sync_mutex);\n+}\n+\n static int\n get_last_valid_idx(struct fdset *pfdset, int last_valid_idx)\n {\n@@ -96,6 +179,12 @@ fdset_add_fd(struct fdset *pfdset, int idx, int fd,\n \tpfd->revents = 0;\n }\n \n+void\n+fdset_uninit(struct fdset *pfdset)\n+{\n+\tfdset_pipe_uninit(pfdset);\n+}\n+\n int\n fdset_init(struct fdset *pfdset)\n {\n@@ -106,8 +195,6 @@ fdset_init(struct fdset *pfdset)\n \n \tpthread_mutex_init(&pfdset->fd_mutex, NULL);\n \tpthread_mutex_init(&pfdset->fd_polling_mutex, NULL);\n-\tpthread_mutex_init(&pfdset->sync_mutex, NULL);\n-\tpthread_cond_init(&pfdset->sync_cond, NULL);\n \n \tfor (i = 0; i < MAX_FDS; i++) {\n \t\tpfdset->fd[i].fd = -1;\n@@ -115,7 +202,7 @@ fdset_init(struct fdset *pfdset)\n \t}\n \tpfdset->num = 0;\n \n-\treturn 0;\n+\treturn fdset_pipe_init(pfdset);\n }\n \n /**\n@@ -145,6 +232,8 @@ fdset_add(struct fdset *pfdset, int fd, fd_cb rcb, fd_cb wcb, void *dat)\n \tfdset_add_fd(pfdset, i, fd, rcb, wcb, dat);\n \tpthread_mutex_unlock(&pfdset->fd_mutex);\n \n+\tfdset_sync(pfdset);\n+\n \treturn 0;\n }\n \n@@ -176,6 +265,8 @@ fdset_del(struct fdset *pfdset, int fd)\n \t\tpthread_mutex_unlock(&pfdset->fd_mutex);\n \t} while (i != -1);\n \n+\tfdset_sync(pfdset);\n+\n \treturn dat;\n }\n \n@@ -209,6 +300,9 @@ fdset_try_del(struct fdset *pfdset, int fd)\n \t}\n \n \tpthread_mutex_unlock(&pfdset->fd_mutex);\n+\n+\tfdset_sync(pfdset);\n+\n \treturn 0;\n }\n \n@@ -314,83 +408,3 @@ fdset_event_dispatch(void *arg)\n \n \treturn 0;\n }\n-\n-static void\n-fdset_pipe_read_cb(int readfd, void *dat,\n-\t\t   int *remove __rte_unused)\n-{\n-\tchar charbuf[16];\n-\tstruct fdset *fdset = dat;\n-\tint r = read(readfd, charbuf, sizeof(charbuf));\n-\t/*\n-\t * Just an optimization, we don't care if read() failed\n-\t * so ignore explicitly its return value to make the\n-\t * compiler happy\n-\t */\n-\tRTE_SET_USED(r);\n-\n-\tpthread_mutex_lock(&fdset->sync_mutex);\n-\tfdset->sync = true;\n-\tpthread_cond_broadcast(&fdset->sync_cond);\n-\tpthread_mutex_unlock(&fdset->sync_mutex);\n-}\n-\n-void\n-fdset_pipe_uninit(struct fdset *fdset)\n-{\n-\tfdset_del(fdset, fdset->u.readfd);\n-\tclose(fdset->u.readfd);\n-\tclose(fdset->u.writefd);\n-}\n-\n-int\n-fdset_pipe_init(struct fdset *fdset)\n-{\n-\tint ret;\n-\n-\tif (pipe(fdset->u.pipefd) < 0) {\n-\t\tVHOST_FDMAN_LOG(ERR,\n-\t\t\t\"failed to create pipe for vhost fdset\");\n-\t\treturn -1;\n-\t}\n-\n-\tret = fdset_add(fdset, fdset->u.readfd,\n-\t\t\tfdset_pipe_read_cb, NULL, fdset);\n-\n-\tif (ret < 0) {\n-\t\tVHOST_FDMAN_LOG(ERR,\n-\t\t\t\"failed to add pipe readfd %d into vhost server fdset\",\n-\t\t\tfdset->u.readfd);\n-\n-\t\tfdset_pipe_uninit(fdset);\n-\t\treturn -1;\n-\t}\n-\n-\treturn 0;\n-}\n-\n-void\n-fdset_pipe_notify(struct fdset *fdset)\n-{\n-\tint r = write(fdset->u.writefd, \"1\", 1);\n-\t/*\n-\t * Just an optimization, we don't care if write() failed\n-\t * so ignore explicitly its return value to make the\n-\t * compiler happy\n-\t */\n-\tRTE_SET_USED(r);\n-}\n-\n-void\n-fdset_pipe_notify_sync(struct fdset *fdset)\n-{\n-\tpthread_mutex_lock(&fdset->sync_mutex);\n-\n-\tfdset->sync = false;\n-\tfdset_pipe_notify(fdset);\n-\n-\twhile (!fdset->sync)\n-\t\tpthread_cond_wait(&fdset->sync_cond, &fdset->sync_mutex);\n-\n-\tpthread_mutex_unlock(&fdset->sync_mutex);\n-}\ndiff --git a/lib/vhost/fd_man.h b/lib/vhost/fd_man.h\nindex 0f4cddfe56..c18e3a435c 100644\n--- a/lib/vhost/fd_man.h\n+++ b/lib/vhost/fd_man.h\n@@ -42,6 +42,7 @@ struct fdset {\n \tbool sync;\n };\n \n+void fdset_uninit(struct fdset *pfdset);\n \n int fdset_init(struct fdset *pfdset);\n \n@@ -53,11 +54,4 @@ int fdset_try_del(struct fdset *pfdset, int fd);\n \n uint32_t fdset_event_dispatch(void *arg);\n \n-int fdset_pipe_init(struct fdset *fdset);\n-\n-void fdset_pipe_uninit(struct fdset *fdset);\n-\n-void fdset_pipe_notify(struct fdset *fdset);\n-void fdset_pipe_notify_sync(struct fdset *fdset);\n-\n #endif\ndiff --git a/lib/vhost/socket.c b/lib/vhost/socket.c\nindex 8155749972..5afb952a21 100644\n--- a/lib/vhost/socket.c\n+++ b/lib/vhost/socket.c\n@@ -278,7 +278,6 @@ vhost_user_add_connection(int fd, struct vhost_user_socket *vsocket)\n \tTAILQ_INSERT_TAIL(&vsocket->conn_list, conn, next);\n \tpthread_mutex_unlock(&vsocket->conn_mutex);\n \n-\tfdset_pipe_notify(&vhost_user.fdset);\n \treturn;\n \n err_cleanup:\n@@ -1186,20 +1185,11 @@ rte_vhost_driver_start(const char *path)\n \t\t\treturn -1;\n \t\t}\n \n-\t\t/**\n-\t\t * create a pipe which will be waited by poll and notified to\n-\t\t * rebuild the wait list of poll.\n-\t\t */\n-\t\tif (fdset_pipe_init(&vhost_user.fdset) < 0) {\n-\t\t\tVHOST_CONFIG_LOG(path, ERR, \"failed to create pipe for vhost fdset\");\n-\t\t\treturn -1;\n-\t\t}\n-\n \t\tint ret = rte_thread_create_internal_control(&fdset_tid,\n \t\t\t\t\"vhost-evt\", fdset_event_dispatch, &vhost_user.fdset);\n \t\tif (ret != 0) {\n \t\t\tVHOST_CONFIG_LOG(path, ERR, \"failed to create fdset handling thread\");\n-\t\t\tfdset_pipe_uninit(&vhost_user.fdset);\n+\t\t\tfdset_uninit(&vhost_user.fdset);\n \t\t\treturn -1;\n \t\t}\n \t}\ndiff --git a/lib/vhost/vduse.c b/lib/vhost/vduse.c\nindex 530c148399..d87fc500d4 100644\n--- a/lib/vhost/vduse.c\n+++ b/lib/vhost/vduse.c\n@@ -225,7 +225,6 @@ vduse_vring_setup(struct virtio_net *dev, unsigned int index)\n \t\t\tclose(vq->kickfd);\n \t\t\tvq->kickfd = VIRTIO_UNINITIALIZED_EVENTFD;\n \t\t}\n-\t\tfdset_pipe_notify(&vduse.fdset);\n \t\tvhost_enable_guest_notification(dev, vq, 1);\n \t\tVHOST_CONFIG_LOG(dev->ifname, INFO, \"Ctrl queue event handler installed\");\n \t}\n@@ -238,10 +237,8 @@ vduse_vring_cleanup(struct virtio_net *dev, unsigned int index)\n \tstruct vduse_vq_eventfd vq_efd;\n \tint ret;\n \n-\tif (vq == dev->cvq && vq->kickfd >= 0) {\n+\tif (vq == dev->cvq && vq->kickfd >= 0)\n \t\tfdset_del(&vduse.fdset, vq->kickfd);\n-\t\tfdset_pipe_notify(&vduse.fdset);\n-\t}\n \n \tvq_efd.index = index;\n \tvq_efd.fd = VDUSE_EVENTFD_DEASSIGN;\n@@ -432,20 +429,11 @@ vduse_device_create(const char *path, bool compliant_ol_flags)\n \t\t\treturn -1;\n \t\t}\n \n-\t\t/**\n-\t\t * create a pipe which will be waited by poll and notified to\n-\t\t * rebuild the wait list of poll.\n-\t\t */\n-\t\tif (fdset_pipe_init(&vduse.fdset) < 0) {\n-\t\t\tVHOST_CONFIG_LOG(path, ERR, \"failed to create pipe for vduse fdset\");\n-\t\t\treturn -1;\n-\t\t}\n-\n \t\tret = rte_thread_create_internal_control(&fdset_tid, \"vduse-evt\",\n \t\t\t\tfdset_event_dispatch, &vduse.fdset);\n \t\tif (ret != 0) {\n \t\t\tVHOST_CONFIG_LOG(path, ERR, \"failed to create vduse fdset handling thread\");\n-\t\t\tfdset_pipe_uninit(&vduse.fdset);\n+\t\t\tfdset_uninit(&vduse.fdset);\n \t\t\treturn -1;\n \t\t}\n \n@@ -573,7 +561,6 @@ vduse_device_create(const char *path, bool compliant_ol_flags)\n \t\t\t\tdev->vduse_dev_fd);\n \t\tgoto out_dev_destroy;\n \t}\n-\tfdset_pipe_notify(&vduse.fdset);\n \n \tfree(dev_config);\n \n@@ -616,7 +603,6 @@ vduse_device_destroy(const char *path)\n \tvduse_device_stop(dev);\n \n \tfdset_del(&vduse.fdset, dev->vduse_dev_fd);\n-\tfdset_pipe_notify_sync(&vduse.fdset);\n \n \tif (dev->vduse_dev_fd >= 0) {\n \t\tclose(dev->vduse_dev_fd);\n",
    "prefixes": [
        "v3",
        "3/5"
    ]
}