From nobody Fri Apr 19 13:03:27 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 1541487174235904.7909528746244; Mon, 5 Nov 2018 22:52:54 -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 41A6430014D2; Tue, 6 Nov 2018 06:52:51 +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 F3076105704D; Tue, 6 Nov 2018 06:52:49 +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 64962180B5B7; Tue, 6 Nov 2018 06:52:46 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id wA66OLNg027414 for ; Tue, 6 Nov 2018 01:24:22 -0500 Received: by smtp.corp.redhat.com (Postfix) id EBF6D611D3; Tue, 6 Nov 2018 06:24:21 +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 F411460BF2; Tue, 6 Nov 2018 06:24:17 +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 835028046B; Tue, 6 Nov 2018 06:24:16 +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 wA66JIKh073145; Tue, 6 Nov 2018 06:24:15 GMT Received: from userv0021.oracle.com (userv0021.oracle.com [156.151.31.71]) by userp2120.oracle.com with ESMTP id 2nh4aqk2wp-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 06 Nov 2018 06:24:15 +0000 Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by userv0021.oracle.com (8.14.4/8.14.4) with ESMTP id wA66OE5u023051 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 6 Nov 2018 06:24:14 GMT Received: from abhmp0010.oracle.com (abhmp0010.oracle.com [141.146.116.16]) by aserv0122.oracle.com (8.14.4/8.14.4) with ESMTP id wA66OEFq007252; Tue, 6 Nov 2018 06:24:14 GMT Received: from localhost.localdomain (/77.138.186.148) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Mon, 05 Nov 2018 22:24:13 -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=vmBFTZzncKTt3vL0CnCUQUVgQ+vWM8ga9oRUqu0CiqM=; b=Kl+n/NmYXv+9UHoo2nzwbcoVLpkI0IG7SlZ8TVtoXovNg8doXS8ENzC785VG3+Vm5FIr wIw7VJ/N5DikodyrXehPsEsQU0DDaH6Rnxp2ACivSFKSVx1t2tWodqNaDvc1Kl50ZPog 22dZW6ASZ/Dt8ur6SDQgdGiMqmDiTTa85IsgYIynY6eJRShiFLyP8pSRhRB1rt7ISUfN UxBMQYvMFwnMcwxOclyhwiVYRAozOYkcC5uH6XVebMPukqqQ+9zel/j1+V2aU5C2j5tQ n7duAuEugA+UhTBosrgX9fWusF53FpFVsCpBDojn9AFMFwWfNn64RJNxnldZ5zDiRlRR qQ== From: Yuval Shaia To: libvir-list@redhat.com, mprivozn@redhat.com, berrange@redhat.com, laine@redhat.com, marcel.apfelbaum@gmail.com Date: Tue, 6 Nov 2018 08:24:02 +0200 Message-Id: <20181106062402.12124-1-yuval.shaia@oracle.com> X-Proofpoint-Virus-Version: vendor=nai engine=5900 definitions=9068 signatures=668683 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=2 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-1807170000 definitions=main-1811060055 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]); Tue, 06 Nov 2018 06:24:16 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Tue, 06 Nov 2018 06:24:16 +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.307 (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.13 X-loop: libvir-list@redhat.com Cc: Yuval Shaia Subject: [libvirt] [PATCH v2] 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.45]); Tue, 06 Nov 2018 06:52:52 +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 --- v1 -> v2: * Address all comments from Michal Privoznik --- 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..4e541abd05 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 =3D {0}; + 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