From patchwork Thu Oct 6 13:12:10 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Greg Kurz X-Patchwork-Id: 9364847 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id B58AF6077E for ; Thu, 6 Oct 2016 13:43:38 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A633129030 for ; Thu, 6 Oct 2016 13:43:38 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9B02429033; Thu, 6 Oct 2016 13:43:38 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 35DC629030 for ; Thu, 6 Oct 2016 13:43:35 +0000 (UTC) Received: from localhost ([::1]:56251 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bs8xS-0007dV-AD for patchwork-qemu-devel@patchwork.kernel.org; Thu, 06 Oct 2016 09:43:34 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:34862) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bs8TJ-0005b3-88 for qemu-devel@nongnu.org; Thu, 06 Oct 2016 09:12:28 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bs8TD-0003fG-Th for qemu-devel@nongnu.org; Thu, 06 Oct 2016 09:12:24 -0400 Received: from mx0b-001b2d01.pphosted.com ([148.163.158.5]:33884 helo=mx0a-001b2d01.pphosted.com) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bs8TD-0003eS-OT for qemu-devel@nongnu.org; Thu, 06 Oct 2016 09:12:19 -0400 Received: from pps.filterd (m0098419.ppops.net [127.0.0.1]) by mx0b-001b2d01.pphosted.com (8.16.0.17/8.16.0.17) with SMTP id u96DArH4031372 for ; Thu, 6 Oct 2016 09:12:17 -0400 Received: from e38.co.us.ibm.com (e38.co.us.ibm.com [32.97.110.159]) by mx0b-001b2d01.pphosted.com with ESMTP id 25wpu8svqp-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Thu, 06 Oct 2016 09:12:17 -0400 Received: from localhost by e38.co.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Thu, 6 Oct 2016 07:12:16 -0600 Received: from d03dlp03.boulder.ibm.com (9.17.202.179) by e38.co.us.ibm.com (192.168.1.138) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Thu, 6 Oct 2016 07:12:13 -0600 Received: from b01cxnp23032.gho.pok.ibm.com (b01cxnp23032.gho.pok.ibm.com [9.57.198.27]) by d03dlp03.boulder.ibm.com (Postfix) with ESMTP id D5C8319D8041; Thu, 6 Oct 2016 07:11:39 -0600 (MDT) Received: from b01ledav006.gho.pok.ibm.com (b01ledav006.gho.pok.ibm.com [9.57.199.111]) by b01cxnp23032.gho.pok.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id u96DBeNj15073694; Thu, 6 Oct 2016 13:12:12 GMT Received: from b01ledav006.gho.pok.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 2E324AC058; Thu, 6 Oct 2016 09:12:12 -0400 (EDT) Received: from [192.168.66.108] (unknown [9.164.137.37]) by b01ledav006.gho.pok.ibm.com (Postfix) with ESMTP id 61D02AC03A; Thu, 6 Oct 2016 09:12:11 -0400 (EDT) From: Greg Kurz To: qemu-devel@nongnu.org Date: Thu, 06 Oct 2016 15:12:10 +0200 User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Content-Scanned: Fidelis XPS MAILER x-cbid: 16100613-0028-0000-0000-000005C14A91 X-IBM-SpamModules-Scores: X-IBM-SpamModules-Versions: BY=3.00005863; HX=3.00000240; KW=3.00000007; PH=3.00000004; SC=3.00000186; SDB=6.00765034; UDB=6.00365497; IPR=6.00540891; BA=6.00004791; NDR=6.00000001; ZLA=6.00000005; ZF=6.00000009; ZB=6.00000000; ZP=6.00000000; ZH=6.00000000; ZU=6.00000002; MB=3.00012894; XFM=3.00000011; UTC=2016-10-06 13:12:15 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 16100613-0029-0000-0000-00002FD169BF Message-Id: <147575953018.4745.3158241454234330045.stgit@bahia> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2016-10-06_05:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 suspectscore=3 malwarescore=0 phishscore=0 adultscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1609300000 definitions=main-1610060233 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [generic] X-Received-From: 148.163.158.5 Subject: [Qemu-devel] [PATCH] virtio-9p: add reset handler X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: "Aneesh Kumar K.V" , Stefan Hajnoczi , "Michael S. Tsirkin" Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Virtio devices should implement the VirtIODevice->reset() function to perform necessary cleanup actions and to bring the device to a quiescent state. In the case of the virtio-9p device, this means: - emptying the list of active PDUs (i.e. draining all in-flight I/O) - freeing all fids (i.e. close open file descriptors and free memory) That's what this patch does. The reset handler first waits for all active PDUs to complete. Since completion happens in the QEMU global aio context, we just have to loop around aio_poll() until the active list is empty. The freeing part involves some actions to be performed on the backend, like closing file descriptors or flushing extended attributes to the underlying filesystem. The virtfs_reset() function already does the job: it calls free_fid() for all open fids not involved in an ongoing I/O operation. We are sure this is the case since we have drained the PDU active list. The current code implements all backend accesses with coroutines, but we want to stay synchronous on the reset path. We can either change the current code to be able to run when not in coroutine context, or create a coroutine context and wait for virtfs_reset() to complete. This patch goes for the latter because it results in simpler code. Note that we also need to create a dummy PDU because it is also an API to pass the FsContext pointer to all backend callbacks. Signed-off-by: Greg Kurz Reviewed-by: Michael S. Tsirkin Reviewed-by: Stefan Hajnoczi --- hw/9pfs/9p.c | 31 +++++++++++++++++++++++++++++++ hw/9pfs/9p.h | 1 + hw/9pfs/virtio-9p-device.c | 8 ++++++++ 3 files changed, 40 insertions(+) diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c index 119ee584969b..42137395037e 100644 --- a/hw/9pfs/9p.c +++ b/hw/9pfs/9p.c @@ -3522,6 +3522,37 @@ void v9fs_device_unrealize_common(V9fsState *s, Error **errp) g_free(s->tag); } + +typedef struct VirtfsCoResetData { + V9fsPDU pdu; + bool done; +} VirtfsCoResetData; + +static void coroutine_fn virtfs_co_reset(void *opaque) +{ + VirtfsCoResetData *data = opaque; + + virtfs_reset(&data->pdu); + data->done = true; +} + +void v9fs_reset(V9fsState *s) +{ + VirtfsCoResetData data = { .pdu = { .s = s }, .done = false }; + Coroutine *co; + + while (!QLIST_EMPTY(&s->active_list)) { + aio_poll(qemu_get_aio_context(), true); + } + + co = qemu_coroutine_create(virtfs_co_reset, &data); + qemu_coroutine_enter(co); + + while (!data.done) { + aio_poll(qemu_get_aio_context(), true); + } +} + static void __attribute__((__constructor__)) v9fs_set_fd_limit(void) { struct rlimit rlim; diff --git a/hw/9pfs/9p.h b/hw/9pfs/9p.h index d539d2ebe9c0..6b69eaf24614 100644 --- a/hw/9pfs/9p.h +++ b/hw/9pfs/9p.h @@ -339,5 +339,6 @@ ssize_t pdu_unmarshal(V9fsPDU *pdu, size_t offset, const char *fmt, ...); V9fsPDU *pdu_alloc(V9fsState *s); void pdu_free(V9fsPDU *pdu); void pdu_submit(V9fsPDU *pdu); +void v9fs_reset(V9fsState *s); #endif diff --git a/hw/9pfs/virtio-9p-device.c b/hw/9pfs/virtio-9p-device.c index 009b43f6d045..b73d72aceb64 100644 --- a/hw/9pfs/virtio-9p-device.c +++ b/hw/9pfs/virtio-9p-device.c @@ -130,6 +130,13 @@ static void virtio_9p_device_unrealize(DeviceState *dev, Error **errp) v9fs_device_unrealize_common(s, errp); } +static void virtio_9p_reset(VirtIODevice *vdev) +{ + V9fsVirtioState *v = (V9fsVirtioState *)vdev; + + v9fs_reset(&v->state); +} + ssize_t virtio_pdu_vmarshal(V9fsPDU *pdu, size_t offset, const char *fmt, va_list ap) { @@ -188,6 +195,7 @@ static void virtio_9p_class_init(ObjectClass *klass, void *data) vdc->unrealize = virtio_9p_device_unrealize; vdc->get_features = virtio_9p_get_features; vdc->get_config = virtio_9p_get_config; + vdc->reset = virtio_9p_reset; } static const TypeInfo virtio_device_info = {