From nobody Fri Mar 29 00:09:53 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=fail(p=none dis=none) header.from=oracle.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1545646542553126.24124641482365; Mon, 24 Dec 2018 02:15:42 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 98FB67F6C5; Mon, 24 Dec 2018 10:15:40 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 456701001943; Mon, 24 Dec 2018 10:15:40 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id DC54218005AD; Mon, 24 Dec 2018 10:15:39 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id wBOAFcLc020815 for ; Mon, 24 Dec 2018 05:15:38 -0500 Received: by smtp.corp.redhat.com (Postfix) id A40425C228; Mon, 24 Dec 2018 10:15:38 +0000 (UTC) Received: from mx1.redhat.com (ext-mx04.extmail.prod.ext.phx2.redhat.com [10.5.110.28]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 4D9F05C1B5; Mon, 24 Dec 2018 10:15:31 +0000 (UTC) Received: from userp2120.oracle.com (userp2120.oracle.com [156.151.31.85]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 50C998046C; Mon, 24 Dec 2018 10:15:29 +0000 (UTC) Received: from pps.filterd (userp2120.oracle.com [127.0.0.1]) by userp2120.oracle.com (8.16.0.22/8.16.0.22) with SMTP id wBOAF2Gf150368; Mon, 24 Dec 2018 10:15:28 GMT Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by userp2120.oracle.com with ESMTP id 2phdwqm9jy-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 24 Dec 2018 10:15:28 +0000 Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by userv0022.oracle.com (8.14.4/8.14.4) with ESMTP id wBOAFMbd001007 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 24 Dec 2018 10:15:22 GMT Received: from abhmp0010.oracle.com (abhmp0010.oracle.com [141.146.116.16]) by userv0121.oracle.com (8.14.4/8.13.8) with ESMTP id wBOAFMX4018807; Mon, 24 Dec 2018 10:15:22 GMT Received: from localhost.localdomain (/77.138.186.148) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Mon, 24 Dec 2018 02:15:21 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : cc : subject : date : message-id; s=corp-2018-07-02; bh=fQ7fKvzLmOo+Tbfa1Lss3O+abbmmc7z+XE7UveizS4g=; b=wS8vLlDc78ax2HAjpGUC5mmxqXY8NDmuhfBKGDREBIeQDRnVkbAp0B99u8fKkgjaKcbd xrm1dNZhCrc9Zh3fzN7z7BqX1u6ib1UJyRiRKbmbZtcx0zGn2yohLnfcPr8k0chrC4xM 0rXoLMTnHNSqJmHgB02yWeNH62wJ/dgZA03FucKlLXTW/XSQnSsPKJJW4ijhEzjkFzoe tpAReB+Wf66Lj9KEnbaQ+Wx7Qm0kOh7t4HsYzIB+2z4C3+UThzchIOz9d/1s4xcT5+0L EOwDl17gXdFrOFmHNYOHez+sweEI+v0WJEFKgzxiyRidZnUrb2CXNltca6Eg5tHSlUfB sg== From: Yuval Shaia To: libvir-list@redhat.com, mprivozn@redhat.com, berrange@redhat.com, laine@redhat.com, marcel.apfelbaum@gmail.com Date: Mon, 24 Dec 2018 12:15:12 +0200 Message-Id: <20181224101512.1605-1-yuval.shaia@oracle.com> X-Proofpoint-Virus-Version: vendor=nai engine=5900 definitions=9116 signatures=668680 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=0 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 mlxscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1812240091 X-Greylist: Sender passed SPF test, Sender IP whitelisted by DNSRBL, ACL 216 matched, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Mon, 24 Dec 2018 10:15:29 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Mon, 24 Dec 2018 10:15:29 +0000 (UTC) for IP:'156.151.31.85' DOMAIN:'userp2120.oracle.com' HELO:'userp2120.oracle.com' FROM:'yuval.shaia@oracle.com' RCPT:'' X-RedHat-Spam-Score: -103.473 (DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, RCVD_IN_DNSWL_MED, SPF_HELO_PASS, SPF_PASS, UNPARSEABLE_RELAY, USER_IN_WHITELIST) 156.151.31.85 userp2120.oracle.com 156.151.31.85 userp2120.oracle.com X-Scanned-By: MIMEDefang 2.78 on 10.5.110.28 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com Cc: Yuval Shaia Subject: [libvirt] [PATCH v3 RESEND] qemu: Process RDMA GID state change event X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.25]); Mon, 24 Dec 2018 10:15:41 +0000 (UTC) X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Type: text/plain; charset="utf-8" This event is emitted on the monitor when a GID table in pvrdma device is modified and the change needs to be propagate to the backend RDMA device's GID table. The control over the RDMA device's GID table is done by updating the device's Ethernet function addresses. Usually the first GID entry is determine by the MAC address, the second by the first IPv6 address and the third by the IPv4 address. Other entries can be added by adding more IP addresses. The opposite is the same, i.e. whenever an address is removed, the corresponding GID entry is removed. The process is done by the network and RDMA stacks. Whenever an address is added the ib_core driver is notified and calls the device driver's add_gid function which in turn update the device. To support this in pvrdma device we need to hook into the create_bind and destroy_bind HW commands triggered by pvrdma driver in guest. Whenever a changed is made to the pvrdma device's GID table a special QMP messages is sent to be processed by libvirt to update the address of the backend Ethernet device. Signed-off-by: Yuval Shaia --- (fixing mail subject from v2 to v3, rest is the same) Hi, Corresponding qemu commit was merged to master as part of the following patch-set: https://www.mail-archive.com/qemu-devel@nongnu.org/msg583387.html Appreciate if this patch can be reviewed and merged as well. Thanks, Yuval v1 -> v2: * Address all comments from Michal Privoznik v2 -> v3: * Remove static initialization in processRdmaGidStatusChangedEvent --- src/qemu/qemu_domain.c | 3 +++ src/qemu/qemu_domain.h | 1 + src/qemu/qemu_driver.c | 44 ++++++++++++++++++++++++++++++ src/qemu/qemu_monitor.c | 27 +++++++++++++++++++ src/qemu/qemu_monitor.h | 27 +++++++++++++++++++ src/qemu/qemu_monitor_json.c | 36 +++++++++++++++++++++++++ src/qemu/qemu_process.c | 52 ++++++++++++++++++++++++++++++++++++ 7 files changed, 190 insertions(+) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index ba3fff607a..8da54c7ee9 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -13479,6 +13479,9 @@ qemuProcessEventFree(struct qemuProcessEvent *event) case QEMU_PROCESS_EVENT_GUESTPANIC: qemuMonitorEventPanicInfoFree(event->data); break; + case QEMU_PROCESS_EVENT_RDMA_GID_STATUS_CHANGED: + qemuMonitorEventRdmaGidStatusFree(event->data); + break; case QEMU_PROCESS_EVENT_WATCHDOG: case QEMU_PROCESS_EVENT_DEVICE_DELETED: case QEMU_PROCESS_EVENT_NIC_RX_FILTER_CHANGED: diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index 80bd4bde91..64bceb9a98 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -487,6 +487,7 @@ typedef enum { QEMU_PROCESS_EVENT_BLOCK_JOB, QEMU_PROCESS_EVENT_MONITOR_EOF, QEMU_PROCESS_EVENT_PR_DISCONNECT, + QEMU_PROCESS_EVENT_RDMA_GID_STATUS_CHANGED, =20 QEMU_PROCESS_EVENT_LAST } qemuProcessEventType; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index a52e2495d5..5c6ab3c0ea 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -4788,6 +4788,47 @@ processPRDisconnectEvent(virDomainObjPtr vm) } =20 =20 +static void +processRdmaGidStatusChangedEvent(virDomainObjPtr vm, + qemuMonitorRdmaGidStatusChangedPrivatePtr= info) +{ + unsigned int prefix_len; + virSocketAddr addr; + int rc; + + if (!virDomainObjIsActive(vm)) + return; + + VIR_DEBUG("netdev=3D%s,gid_status=3D%d,subnet_prefix=3D0x%llx,interfac= e_id=3D0x%llx", + info->netdev, info->gid_status, info->subnet_prefix, + info->interface_id); + + if (info->subnet_prefix) { + prefix_len =3D 64; + uint32_t ipv6[4]; + memcpy(&ipv6[0], &info->subnet_prefix, sizeof(info->subnet_prefix)= ); + memcpy(&ipv6[2], &info->interface_id, sizeof(info->interface_id)); + virSocketAddrSetIPv6AddrNetOrder(&addr, ipv6); + } else { + prefix_len =3D 24; + virSocketAddrSetIPv4AddrNetOrder(&addr, info->interface_id >> 32); + } + + if (info->gid_status) { + VIR_DEBUG("Adding %s to %s", virSocketAddrFormat(&addr), info->net= dev); + rc =3D virNetDevIPAddrAdd(info->netdev, &addr, NULL, prefix_len); + } else { + VIR_DEBUG("Removing %s from %s", virSocketAddrFormat(&addr), + info->netdev); + rc =3D virNetDevIPAddrDel(info->netdev, &addr, prefix_len); + } + + if (rc < 0) + VIR_WARN("Fail to update address %s to %s", virSocketAddrFormat(&a= ddr), + info->netdev); +} + + static void qemuProcessEventHandler(void *data, void *opaque) { struct qemuProcessEvent *processEvent =3D data; @@ -4828,6 +4869,9 @@ static void qemuProcessEventHandler(void *data, void = *opaque) case QEMU_PROCESS_EVENT_PR_DISCONNECT: processPRDisconnectEvent(vm); break; + case QEMU_PROCESS_EVENT_RDMA_GID_STATUS_CHANGED: + processRdmaGidStatusChangedEvent(vm, processEvent->data); + break; case QEMU_PROCESS_EVENT_LAST: break; } diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 7f7013e115..4bf71dbf8c 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -1686,6 +1686,22 @@ qemuMonitorEmitPRManagerStatusChanged(qemuMonitorPtr= mon, } =20 =20 +int +qemuMonitorEmitRdmaGidStatusChanged(qemuMonitorPtr mon, const char *netdev, + bool gid_status, uint64_t subnet_prefi= x, + uint64_t interface_id) +{ + int ret =3D -1; + VIR_DEBUG("netdev=3D%s,gid_status=3D%d,subnet_prefix=3D0x%lx,interface= _id=3D0x%lx", + netdev, gid_status, subnet_prefix, interface_id); + + QEMU_MONITOR_CALLBACK(mon, ret, domainRdmaGidStatusChanged, mon->vm, n= etdev, + gid_status, subnet_prefix, interface_id); + + return ret; +} + + int qemuMonitorSetCapabilities(qemuMonitorPtr mon) { @@ -4298,6 +4314,17 @@ qemuMonitorEventPanicInfoFree(qemuMonitorEventPanicI= nfoPtr info) } =20 =20 +void +qemuMonitorEventRdmaGidStatusFree(qemuMonitorRdmaGidStatusChangedPrivatePt= r info) +{ + if (!info) + return; + + VIR_FREE(info->netdev); + VIR_FREE(info); +} + + int qemuMonitorSetWatchdogAction(qemuMonitorPtr mon, const char *action) diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index 48b142a4f4..b639a0a9d2 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -109,8 +109,22 @@ struct _qemuMonitorEventPanicInfo { } data; }; =20 + +typedef struct _qemuMonitorRdmaGidStatusChangedPrivate qemuMonitorRdmaGidS= tatusChangedPrivate; +typedef qemuMonitorRdmaGidStatusChangedPrivate *qemuMonitorRdmaGidStatusCh= angedPrivatePtr; +struct _qemuMonitorRdmaGidStatusChangedPrivate { + virObject parent; + + char *netdev; + bool gid_status; + unsigned long long subnet_prefix; + unsigned long long interface_id; +}; + + char *qemuMonitorGuestPanicEventInfoFormatMsg(qemuMonitorEventPanicInfoPtr= info); void qemuMonitorEventPanicInfoFree(qemuMonitorEventPanicInfoPtr info); +void qemuMonitorEventRdmaGidStatusFree(qemuMonitorRdmaGidStatusChangedPriv= atePtr info); =20 typedef void (*qemuMonitorDestroyCallback)(qemuMonitorPtr mon, virDomainObjPtr vm, @@ -281,6 +295,14 @@ typedef int (*qemuMonitorDomainPRManagerStatusChangedC= allback)(qemuMonitorPtr mo bool connec= ted, void *opaqu= e); =20 +typedef int (*qemuMonitorDomainRdmaGidStatusChangedCallback)(qemuMonitorPt= r mon, + virDomainObjP= tr vm, + const char *n= etdev, + bool gid_stat= us, + uint64_t subn= et_prefix, + uint64_t inte= rface_id, + void *opaque); + typedef struct _qemuMonitorCallbacks qemuMonitorCallbacks; typedef qemuMonitorCallbacks *qemuMonitorCallbacksPtr; struct _qemuMonitorCallbacks { @@ -314,6 +336,7 @@ struct _qemuMonitorCallbacks { qemuMonitorDomainBlockThresholdCallback domainBlockThreshold; qemuMonitorDomainDumpCompletedCallback domainDumpCompleted; qemuMonitorDomainPRManagerStatusChangedCallback domainPRManagerStatusC= hanged; + qemuMonitorDomainRdmaGidStatusChangedCallback domainRdmaGidStatusChang= ed; }; =20 char *qemuMonitorEscapeArg(const char *in); @@ -448,6 +471,10 @@ int qemuMonitorEmitPRManagerStatusChanged(qemuMonitorP= tr mon, const char *prManager, bool connected); =20 +int qemuMonitorEmitRdmaGidStatusChanged(qemuMonitorPtr mon, const char *ne= tdev, + bool gid_status, uint64_t subnet_p= refix, + uint64_t interface_id); + int qemuMonitorStartCPUs(qemuMonitorPtr mon); int qemuMonitorStopCPUs(qemuMonitorPtr mon); =20 diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index 3de298c9e2..8df9b426ba 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -91,6 +91,7 @@ static void qemuMonitorJSONHandleAcpiOstInfo(qemuMonitorP= tr mon, virJSONValuePtr static void qemuMonitorJSONHandleBlockThreshold(qemuMonitorPtr mon, virJSO= NValuePtr data); static void qemuMonitorJSONHandleDumpCompleted(qemuMonitorPtr mon, virJSON= ValuePtr data); static void qemuMonitorJSONHandlePRManagerStatusChanged(qemuMonitorPtr mon= , virJSONValuePtr data); +static void qemuMonitorJSONHandleRdmaGidStatusChanged(qemuMonitorPtr mon, = virJSONValuePtr data); =20 typedef struct { const char *type; @@ -114,6 +115,7 @@ static qemuEventHandler eventHandlers[] =3D { { "NIC_RX_FILTER_CHANGED", qemuMonitorJSONHandleNicRxFilterChanged, }, { "POWERDOWN", qemuMonitorJSONHandlePowerdown, }, { "PR_MANAGER_STATUS_CHANGED", qemuMonitorJSONHandlePRManagerStatusCha= nged, }, + { "RDMA_GID_STATUS_CHANGED", qemuMonitorJSONHandleRdmaGidStatusChanged= , }, { "RESET", qemuMonitorJSONHandleReset, }, { "RESUME", qemuMonitorJSONHandleResume, }, { "RTC_CHANGE", qemuMonitorJSONHandleRTCChange, }, @@ -1351,6 +1353,40 @@ static void qemuMonitorJSONHandlePRManagerStatusChan= ged(qemuMonitorPtr mon, } =20 =20 +static void qemuMonitorJSONHandleRdmaGidStatusChanged(qemuMonitorPtr mon, + virJSONValuePtr data) +{ + const char *netdev; + bool gid_status; + unsigned long long subnet_prefix, interface_id; + + if (!(netdev =3D virJSONValueObjectGetString(data, "netdev"))) { + VIR_WARN("missing netdev in GID_STATUS_CHANGED event"); + return; + } + + if (virJSONValueObjectGetBoolean(data, "gid-status", &gid_status)) { + VIR_WARN("missing gid-status in GID_STATUS_CHANGED event"); + return; + } + + if (virJSONValueObjectGetNumberUlong(data, "subnet-prefix", + &subnet_prefix)) { + VIR_WARN("missing subnet-prefix in GID_STATUS_CHANGED event"); + return; + } + + if (virJSONValueObjectGetNumberUlong(data, "interface-id", + &interface_id)) { + VIR_WARN("missing interface-id in GID_STATUS_CHANGED event"); + return; + } + + qemuMonitorEmitRdmaGidStatusChanged(mon, netdev, gid_status, subnet_pr= efix, + interface_id); +} + + int qemuMonitorJSONHumanCommandWithFd(qemuMonitorPtr mon, const char *cmd_str, diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 9cf971808c..6cf0ace5cf 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -1703,6 +1703,57 @@ qemuProcessHandlePRManagerStatusChanged(qemuMonitorP= tr mon ATTRIBUTE_UNUSED, } =20 =20 +static int +qemuProcessHandleRdmaGidStatusChanged(qemuMonitorPtr mon ATTRIBUTE_UNUSED, + virDomainObjPtr vm, const char *netd= ev, + bool gid_status, uint64_t subnet_pre= fix, + uint64_t interface_id, void *opaque) +{ + virQEMUDriverPtr driver =3D opaque; + struct qemuProcessEvent *processEvent =3D NULL; + qemuMonitorRdmaGidStatusChangedPrivatePtr rdmaGitStatusChangedPriv =3D= NULL; + int ret =3D -1; + + virObjectLock(vm); + + VIR_DEBUG("netdev=3D%s,gid_status=3D%d,subnet_prefix=3D0x%lx,interface= _id=3D0x%lx", + netdev, gid_status, subnet_prefix, interface_id); + + if (VIR_ALLOC(rdmaGitStatusChangedPriv) < 0) + goto out_unlock; + + if (VIR_STRDUP(rdmaGitStatusChangedPriv->netdev, netdev) < 0) + goto out_free; + + rdmaGitStatusChangedPriv->gid_status =3D gid_status; + rdmaGitStatusChangedPriv->subnet_prefix =3D subnet_prefix; + rdmaGitStatusChangedPriv->interface_id =3D interface_id; + + if (VIR_ALLOC(processEvent) < 0) + goto out_free; + + processEvent->eventType =3D QEMU_PROCESS_EVENT_RDMA_GID_STATUS_CHANGED; + processEvent->vm =3D virObjectRef(vm); + processEvent->data =3D rdmaGitStatusChangedPriv; + + if (virThreadPoolSendJob(driver->workerPool, 0, processEvent) < 0) { + qemuProcessEventFree(processEvent); + virObjectUnref(vm); + goto out_free; + } + + ret =3D 0; + goto out_unlock; + + out_free: + qemuMonitorEventRdmaGidStatusFree(rdmaGitStatusChangedPriv); + + out_unlock: + virObjectUnlock(vm); + return ret; +} + + static qemuMonitorCallbacks monitorCallbacks =3D { .eofNotify =3D qemuProcessHandleMonitorEOF, .errorNotify =3D qemuProcessHandleMonitorError, @@ -1732,6 +1783,7 @@ static qemuMonitorCallbacks monitorCallbacks =3D { .domainBlockThreshold =3D qemuProcessHandleBlockThreshold, .domainDumpCompleted =3D qemuProcessHandleDumpCompleted, .domainPRManagerStatusChanged =3D qemuProcessHandlePRManagerStatusChan= ged, + .domainRdmaGidStatusChanged =3D qemuProcessHandleRdmaGidStatusChanged, }; =20 static void --=20 2.17.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list