From patchwork Mon May 11 16:09:45 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxim Levitsky X-Patchwork-Id: 11541261 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 49A6392A for ; Mon, 11 May 2020 16:11:14 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 214152070B for ; Mon, 11 May 2020 16:11:13 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="MCkO2T+m" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 214152070B Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:56456 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jYB1N-0003sE-3v for patchwork-qemu-devel@patchwork.kernel.org; Mon, 11 May 2020 12:11:13 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:48214) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jYB0G-00028D-R7 for qemu-devel@nongnu.org; Mon, 11 May 2020 12:10:04 -0400 Received: from us-smtp-delivery-1.mimecast.com ([205.139.110.120]:44719 helo=us-smtp-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1jYB0G-000140-0y for qemu-devel@nongnu.org; Mon, 11 May 2020 12:10:04 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1589213402; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:content-type:content-type:in-reply-to:in-reply-to: references:references; bh=LqVzIZeE/iyxPQdzaM/w9wa3okOVbVjc1YkNbxM6+O8=; b=MCkO2T+mhC+wB4FLVCRT1xvBWOKa6p5gPZmO6iTEfbIQyiv0Wul7Epkr8sddVRcs7jbOUA Pijk3EMZ2qZapcju/SyJrGbaTqC4caKqBbhVmGQEDtQqX2M0iPGbyRVhcN/9JG+4Oe1Vgq x2Q/blkDxE97b1u7hXQOtnbYpJ3fOZk= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-176-7IGT1_-MNsy0ZlNrZjQD6w-1; Mon, 11 May 2020 12:10:00 -0400 X-MC-Unique: 7IGT1_-MNsy0ZlNrZjQD6w-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id C38D2107ACCA; Mon, 11 May 2020 16:09:59 +0000 (UTC) Received: from maximlenovopc.usersys.redhat.com (unknown [10.35.206.222]) by smtp.corp.redhat.com (Postfix) with ESMTP id DF4F25C1B5; Mon, 11 May 2020 16:09:57 +0000 (UTC) From: Maxim Levitsky To: qemu-devel@nongnu.org Subject: [PATCH v2 1/7] scsi/scsi_bus: switch search direction in scsi_device_find Date: Mon, 11 May 2020 19:09:45 +0300 Message-Id: <20200511160951.8733-2-mlevitsk@redhat.com> In-Reply-To: <20200511160951.8733-1-mlevitsk@redhat.com> References: <20200511160951.8733-1-mlevitsk@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=205.139.110.120; envelope-from=mlevitsk@redhat.com; helo=us-smtp-1.mimecast.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/05/11 00:05:06 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, SPF_PASS=-0.001 autolearn=_AUTOLEARN X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Fam Zheng , =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= , Eduardo Habkost , "Michael S. Tsirkin" , Maxim Levitsky , Paolo Bonzini Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" This change will allow us to convert the bus children list to RCU, while not changing the logic of this function Signed-off-by: Maxim Levitsky Reviewed-by: Stefan Hajnoczi --- hw/scsi/scsi-bus.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c index 1c980cab38..7bbc37acec 100644 --- a/hw/scsi/scsi-bus.c +++ b/hw/scsi/scsi-bus.c @@ -1584,7 +1584,7 @@ SCSIDevice *scsi_device_find(SCSIBus *bus, int channel, int id, int lun) BusChild *kid; SCSIDevice *target_dev = NULL; - QTAILQ_FOREACH_REVERSE(kid, &bus->qbus.children, sibling) { + QTAILQ_FOREACH(kid, &bus->qbus.children, sibling) { DeviceState *qdev = kid->child; SCSIDevice *dev = SCSI_DEVICE(qdev); @@ -1592,7 +1592,15 @@ SCSIDevice *scsi_device_find(SCSIBus *bus, int channel, int id, int lun) if (dev->lun == lun) { return dev; } - target_dev = dev; + + /* + * If we don't find exact match (channel/bus/lun), + * we will return the first device which matches channel/bus + */ + + if (!target_dev) { + target_dev = dev; + } } } return target_dev; From patchwork Mon May 11 16:09:46 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxim Levitsky X-Patchwork-Id: 11541269 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E3643912 for ; Mon, 11 May 2020 16:14:01 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id B91B0206E6 for ; Mon, 11 May 2020 16:14:01 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="G+FoyOMI" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org B91B0206E6 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:39478 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jYB44-0000kV-TJ for patchwork-qemu-devel@patchwork.kernel.org; Mon, 11 May 2020 12:14:00 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:48226) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jYB0J-0002C1-5h for qemu-devel@nongnu.org; Mon, 11 May 2020 12:10:07 -0400 Received: from us-smtp-1.mimecast.com ([207.211.31.81]:32358 helo=us-smtp-delivery-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1jYB0I-00014k-6W for qemu-devel@nongnu.org; Mon, 11 May 2020 12:10:06 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1589213405; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:content-type:content-type:in-reply-to:in-reply-to: references:references; bh=MtXFuOOm3cWbAtx6CbAfAbc97uTwRwSIWWwQ7gjw+kU=; b=G+FoyOMIvIggkSwjdmfLspszVM+aN1ozboYQuAIjIOaxKj5NJJwpYfkKoekZPJ9lsRfagJ rGmc5nEutCuKd+oIoNg4TdzsBzgqKxw32tfNBYifejlGSJsCUjUI1gDWac9uBNlhFaw5HO gtwTunyOm4EaknQnNS8KqNV152/DM68= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-317-0OkGEouIOCKBksrRXnpGaA-1; Mon, 11 May 2020 12:10:03 -0400 X-MC-Unique: 0OkGEouIOCKBksrRXnpGaA-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 178E5107ACCA; Mon, 11 May 2020 16:10:02 +0000 (UTC) Received: from maximlenovopc.usersys.redhat.com (unknown [10.35.206.222]) by smtp.corp.redhat.com (Postfix) with ESMTP id 309185C1B5; Mon, 11 May 2020 16:09:59 +0000 (UTC) From: Maxim Levitsky To: qemu-devel@nongnu.org Subject: [PATCH v2 2/7] Implement drain_call_rcu and use it in hmp_device_del Date: Mon, 11 May 2020 19:09:46 +0300 Message-Id: <20200511160951.8733-3-mlevitsk@redhat.com> In-Reply-To: <20200511160951.8733-1-mlevitsk@redhat.com> References: <20200511160951.8733-1-mlevitsk@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=207.211.31.81; envelope-from=mlevitsk@redhat.com; helo=us-smtp-delivery-1.mimecast.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/05/11 01:43:51 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] [fuzzy] X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, SPF_PASS=-0.001 autolearn=_AUTOLEARN X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Fam Zheng , =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= , Eduardo Habkost , "Michael S. Tsirkin" , Maxim Levitsky , Paolo Bonzini Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" This allows to preserve the semantics of hmp_device_del, that the device is deleted immediatly which was changed by previos patch that delayed this to RCU callback Suggested-by: Stefan Hajnoczi Signed-off-by: Maxim Levitsky Reviewed-by: Stefan Hajnoczi --- include/qemu/rcu.h | 1 + qdev-monitor.c | 3 +++ util/rcu.c | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 37 insertions(+) diff --git a/include/qemu/rcu.h b/include/qemu/rcu.h index 570aa603eb..0e375ebe13 100644 --- a/include/qemu/rcu.h +++ b/include/qemu/rcu.h @@ -133,6 +133,7 @@ struct rcu_head { }; extern void call_rcu1(struct rcu_head *head, RCUCBFunc *func); +extern void drain_call_rcu(void); /* The operands of the minus operator must have the same type, * which must be the one that we specify in the cast. diff --git a/qdev-monitor.c b/qdev-monitor.c index 56cee1483f..70877840a2 100644 --- a/qdev-monitor.c +++ b/qdev-monitor.c @@ -812,6 +812,8 @@ void qmp_device_add(QDict *qdict, QObject **ret_data, Error **errp) return; } dev = qdev_device_add(opts, &local_err); + drain_call_rcu(); + if (!dev) { error_propagate(errp, local_err); qemu_opts_del(opts); @@ -904,6 +906,7 @@ void qmp_device_del(const char *id, Error **errp) } qdev_unplug(dev, errp); + drain_call_rcu(); } } diff --git a/util/rcu.c b/util/rcu.c index 60a37f72c3..e8b1c4d6c5 100644 --- a/util/rcu.c +++ b/util/rcu.c @@ -293,6 +293,39 @@ void call_rcu1(struct rcu_head *node, void (*func)(struct rcu_head *node)) qemu_event_set(&rcu_call_ready_event); } + +struct rcu_drain { + struct rcu_head rcu; + QemuEvent drain_complete_event; +}; + +static void drain_rcu_callback(struct rcu_head *node) +{ + struct rcu_drain *event = (struct rcu_drain *)node; + qemu_event_set(&event->drain_complete_event); +} + +void drain_call_rcu(void) +{ + struct rcu_drain rcu_drain; + bool locked = qemu_mutex_iothread_locked(); + + memset(&rcu_drain, 0, sizeof(struct rcu_drain)); + + if (locked) { + qemu_mutex_unlock_iothread(); + } + + qemu_event_init(&rcu_drain.drain_complete_event, false); + call_rcu1(&rcu_drain.rcu, drain_rcu_callback); + qemu_event_wait(&rcu_drain.drain_complete_event); + + if (locked) { + qemu_mutex_lock_iothread(); + } + +} + void rcu_register_thread(void) { assert(rcu_reader.ctr == 0); From patchwork Mon May 11 16:09:47 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxim Levitsky X-Patchwork-Id: 11541265 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id ABC32912 for ; Mon, 11 May 2020 16:12:13 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 82E3D2070B for ; Mon, 11 May 2020 16:12:13 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="fOvOAEvp" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 82E3D2070B Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:60604 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jYB2K-0005as-Lz for patchwork-qemu-devel@patchwork.kernel.org; Mon, 11 May 2020 12:12:12 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:48246) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jYB0O-0002LY-St for qemu-devel@nongnu.org; Mon, 11 May 2020 12:10:12 -0400 Received: from us-smtp-delivery-1.mimecast.com ([207.211.31.120]:57029 helo=us-smtp-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1jYB0N-00016m-N6 for qemu-devel@nongnu.org; Mon, 11 May 2020 12:10:12 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1589213410; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:content-type:content-type:in-reply-to:in-reply-to: references:references; bh=3ML6lECeaqVQT5MGrBV/oBAq/3bu8IGqgGkuLlw17bo=; b=fOvOAEvpy4j9qiJKAYrMn8BOH0dPTnYISGfMKsMQmM+IMD+lANyjyXqZh7En8yLl3xHwGu yWnlLpg8HBwrxbv9viCUa9JI7MnARTLrhKc9U8cZBQSl4rrCbtmdL/tnCKQMcV0qi6120+ 90n51cbE9hGO2TcFvcYcBAKqp0JJpvQ= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-61-2tHjkLXRNRqCVLei7fNW4g-1; Mon, 11 May 2020 12:10:09 -0400 X-MC-Unique: 2tHjkLXRNRqCVLei7fNW4g-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 1FF33107ACF3; Mon, 11 May 2020 16:10:08 +0000 (UTC) Received: from maximlenovopc.usersys.redhat.com (unknown [10.35.206.222]) by smtp.corp.redhat.com (Postfix) with ESMTP id 786AF5C1B5; Mon, 11 May 2020 16:10:02 +0000 (UTC) From: Maxim Levitsky To: qemu-devel@nongnu.org Subject: [PATCH v2 3/7] device-core: use RCU for list of childs of a bus Date: Mon, 11 May 2020 19:09:47 +0300 Message-Id: <20200511160951.8733-4-mlevitsk@redhat.com> In-Reply-To: <20200511160951.8733-1-mlevitsk@redhat.com> References: <20200511160951.8733-1-mlevitsk@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=207.211.31.120; envelope-from=mlevitsk@redhat.com; helo=us-smtp-1.mimecast.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/05/11 02:55:57 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] [fuzzy] X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, SPF_PASS=-0.001 autolearn=_AUTOLEARN X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Fam Zheng , =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= , Eduardo Habkost , "Michael S. Tsirkin" , Maxim Levitsky , Paolo Bonzini Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" This fixes the race between device emulation code that tries to find a child device to dispatch the request to (e.g a scsi disk), and hotplug of a new device to that bus. Note that this doesn't convert all the readers of the list but only these that might go over that list without BQL held. This is a very small first step to make this code thread safe. Suggested-by: Paolo Bonzini Signed-off-by: Maxim Levitsky --- hw/core/bus.c | 36 +++++++++++++++++++++++------------- hw/core/qdev.c | 37 +++++++++++++++++++++++-------------- hw/scsi/scsi-bus.c | 17 ++++++++++++++--- hw/scsi/virtio-scsi.c | 6 +++++- include/hw/qdev-core.h | 3 +++ 5 files changed, 68 insertions(+), 31 deletions(-) diff --git a/hw/core/bus.c b/hw/core/bus.c index 3dc0a825f0..dd6b155ff1 100644 --- a/hw/core/bus.c +++ b/hw/core/bus.c @@ -49,12 +49,14 @@ int qbus_walk_children(BusState *bus, } } - QTAILQ_FOREACH(kid, &bus->children, sibling) { - err = qdev_walk_children(kid->child, - pre_devfn, pre_busfn, - post_devfn, post_busfn, opaque); - if (err < 0) { - return err; + WITH_RCU_READ_LOCK_GUARD() { + QTAILQ_FOREACH_RCU(kid, &bus->children, sibling) { + err = qdev_walk_children(kid->child, + pre_devfn, pre_busfn, + post_devfn, post_busfn, opaque); + if (err < 0) { + return err; + } } } @@ -90,9 +92,13 @@ static void bus_reset_child_foreach(Object *obj, ResettableChildCallback cb, BusState *bus = BUS(obj); BusChild *kid; - QTAILQ_FOREACH(kid, &bus->children, sibling) { + rcu_read_lock(); + + QTAILQ_FOREACH_RCU(kid, &bus->children, sibling) { cb(OBJECT(kid->child), opaque, type); } + + rcu_read_unlock(); } static void qbus_realize(BusState *bus, DeviceState *parent, const char *name) @@ -185,14 +191,18 @@ static void bus_set_realized(Object *obj, bool value, Error **errp) /* TODO: recursive realization */ } else if (!value && bus->realized) { - QTAILQ_FOREACH(kid, &bus->children, sibling) { - DeviceState *dev = kid->child; - object_property_set_bool(OBJECT(dev), false, "realized", - &local_err); - if (local_err != NULL) { - break; + + WITH_RCU_READ_LOCK_GUARD() { + QTAILQ_FOREACH_RCU(kid, &bus->children, sibling) { + DeviceState *dev = kid->child; + object_property_set_bool(OBJECT(dev), false, "realized", + &local_err); + if (local_err != NULL) { + break; + } } } + if (bc->unrealize && local_err == NULL) { bc->unrealize(bus, &local_err); } diff --git a/hw/core/qdev.c b/hw/core/qdev.c index dd77a56067..732789e2b7 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -51,6 +51,12 @@ const VMStateDescription *qdev_get_vmsd(DeviceState *dev) return dc->vmsd; } +static void bus_free_bus_child(BusChild *kid) +{ + object_unref(OBJECT(kid->child)); + g_free(kid); +} + static void bus_remove_child(BusState *bus, DeviceState *child) { BusChild *kid; @@ -60,15 +66,16 @@ static void bus_remove_child(BusState *bus, DeviceState *child) char name[32]; snprintf(name, sizeof(name), "child[%d]", kid->index); - QTAILQ_REMOVE(&bus->children, kid, sibling); + QTAILQ_REMOVE_RCU(&bus->children, kid, sibling); bus->num_children--; /* This gives back ownership of kid->child back to us. */ object_property_del(OBJECT(bus), name, NULL); - object_unref(OBJECT(kid->child)); - g_free(kid); - return; + + /* free the bus kid, when it is safe to do so*/ + call_rcu(kid, bus_free_bus_child, rcu); + break; } } } @@ -83,7 +90,7 @@ static void bus_add_child(BusState *bus, DeviceState *child) kid->child = child; object_ref(OBJECT(kid->child)); - QTAILQ_INSERT_HEAD(&bus->children, kid, sibling); + QTAILQ_INSERT_HEAD_RCU(&bus->children, kid, sibling); /* This transfers ownership of kid->child to the property. */ snprintf(name, sizeof(name), "child[%d]", kid->index); @@ -682,17 +689,19 @@ DeviceState *qdev_find_recursive(BusState *bus, const char *id) DeviceState *ret; BusState *child; - QTAILQ_FOREACH(kid, &bus->children, sibling) { - DeviceState *dev = kid->child; + WITH_RCU_READ_LOCK_GUARD() { + QTAILQ_FOREACH_RCU(kid, &bus->children, sibling) { + DeviceState *dev = kid->child; - if (dev->id && strcmp(dev->id, id) == 0) { - return dev; - } + if (dev->id && strcmp(dev->id, id) == 0) { + return dev; + } - QLIST_FOREACH(child, &dev->child_bus, sibling) { - ret = qdev_find_recursive(child, id); - if (ret) { - return ret; + QLIST_FOREACH(child, &dev->child_bus, sibling) { + ret = qdev_find_recursive(child, id); + if (ret) { + return ret; + } } } } diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c index 7bbc37acec..2bf6d005f3 100644 --- a/hw/scsi/scsi-bus.c +++ b/hw/scsi/scsi-bus.c @@ -412,7 +412,10 @@ static bool scsi_target_emulate_report_luns(SCSITargetReq *r) id = r->req.dev->id; found_lun0 = false; n = 0; - QTAILQ_FOREACH(kid, &r->req.bus->qbus.children, sibling) { + + rcu_read_lock(); + + QTAILQ_FOREACH_RCU(kid, &r->req.bus->qbus.children, sibling) { DeviceState *qdev = kid->child; SCSIDevice *dev = SCSI_DEVICE(qdev); @@ -433,7 +436,7 @@ static bool scsi_target_emulate_report_luns(SCSITargetReq *r) memset(r->buf, 0, len); stl_be_p(&r->buf[0], n); i = found_lun0 ? 8 : 16; - QTAILQ_FOREACH(kid, &r->req.bus->qbus.children, sibling) { + QTAILQ_FOREACH_RCU(kid, &r->req.bus->qbus.children, sibling) { DeviceState *qdev = kid->child; SCSIDevice *dev = SCSI_DEVICE(qdev); @@ -442,6 +445,9 @@ static bool scsi_target_emulate_report_luns(SCSITargetReq *r) i += 8; } } + + rcu_read_unlock(); + assert(i == n + 8); r->len = len; return true; @@ -1584,12 +1590,15 @@ SCSIDevice *scsi_device_find(SCSIBus *bus, int channel, int id, int lun) BusChild *kid; SCSIDevice *target_dev = NULL; - QTAILQ_FOREACH(kid, &bus->qbus.children, sibling) { + rcu_read_lock(); + + QTAILQ_FOREACH_RCU(kid, &bus->qbus.children, sibling) { DeviceState *qdev = kid->child; SCSIDevice *dev = SCSI_DEVICE(qdev); if (dev->channel == channel && dev->id == id) { if (dev->lun == lun) { + rcu_read_unlock(); return dev; } @@ -1603,6 +1612,8 @@ SCSIDevice *scsi_device_find(SCSIBus *bus, int channel, int id, int lun) } } } + + rcu_read_unlock(); return target_dev; } diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c index 472bbd233b..b0f4a35f81 100644 --- a/hw/scsi/virtio-scsi.c +++ b/hw/scsi/virtio-scsi.c @@ -367,12 +367,16 @@ static int virtio_scsi_do_tmf(VirtIOSCSI *s, VirtIOSCSIReq *req) case VIRTIO_SCSI_T_TMF_I_T_NEXUS_RESET: target = req->req.tmf.lun[1]; s->resetting++; - QTAILQ_FOREACH(kid, &s->bus.qbus.children, sibling) { + + rcu_read_lock(); + QTAILQ_FOREACH_RCU(kid, &s->bus.qbus.children, sibling) { d = SCSI_DEVICE(kid->child); if (d->channel == 0 && d->id == target) { qdev_reset_all(&d->qdev); } } + rcu_read_unlock(); + s->resetting--; break; diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h index d87d989e72..ef47cb2d9c 100644 --- a/include/hw/qdev-core.h +++ b/include/hw/qdev-core.h @@ -3,6 +3,8 @@ #include "qemu/queue.h" #include "qemu/bitmap.h" +#include "qemu/rcu.h" +#include "qemu/rcu_queue.h" #include "qom/object.h" #include "hw/hotplug.h" #include "hw/resettable.h" @@ -230,6 +232,7 @@ struct BusClass { }; typedef struct BusChild { + struct rcu_head rcu; DeviceState *child; int index; QTAILQ_ENTRY(BusChild) sibling; From patchwork Mon May 11 16:09:48 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxim Levitsky X-Patchwork-Id: 11541263 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 06A6B912 for ; Mon, 11 May 2020 16:11:35 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id D0B362070B for ; Mon, 11 May 2020 16:11:34 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="D94j3Vr9" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org D0B362070B Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:57610 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jYB1h-0004Na-Vo for patchwork-qemu-devel@patchwork.kernel.org; Mon, 11 May 2020 12:11:34 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:48262) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jYB0U-0002UR-1x for qemu-devel@nongnu.org; Mon, 11 May 2020 12:10:18 -0400 Received: from us-smtp-2.mimecast.com ([205.139.110.61]:39451 helo=us-smtp-delivery-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1jYB0T-00019P-6B for qemu-devel@nongnu.org; Mon, 11 May 2020 12:10:17 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1589213416; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:content-type:content-type:in-reply-to:in-reply-to: references:references; bh=P4QIO4kgNzm3qXY393mDHSXk7baXBdVjmzR7Zrg69Ik=; b=D94j3Vr9BNpT3QCxTUf7qCg+qQfqnJ2ROWTJB4bzZuYotk9ynnfMCZHjkkujNvEIoj249j jftycTUGIaAIMh6tj2jTZt6DZv4rzP4z6SllHB5HnVRbUGOWG8R/Jhodyz55y+BEWmQqfN pQ21xtVZuwie063y3iRdNfGS1Ldndfg= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-434-VGBZvO5nMcOEAO_HGQXfAw-1; Mon, 11 May 2020 12:10:11 -0400 X-MC-Unique: VGBZvO5nMcOEAO_HGQXfAw-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 66870100CCC0; Mon, 11 May 2020 16:10:10 +0000 (UTC) Received: from maximlenovopc.usersys.redhat.com (unknown [10.35.206.222]) by smtp.corp.redhat.com (Postfix) with ESMTP id 80AAD5C1B5; Mon, 11 May 2020 16:10:08 +0000 (UTC) From: Maxim Levitsky To: qemu-devel@nongnu.org Subject: [PATCH v2 4/7] device-core: use atomic_set on .realized property Date: Mon, 11 May 2020 19:09:48 +0300 Message-Id: <20200511160951.8733-5-mlevitsk@redhat.com> In-Reply-To: <20200511160951.8733-1-mlevitsk@redhat.com> References: <20200511160951.8733-1-mlevitsk@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=205.139.110.61; envelope-from=mlevitsk@redhat.com; helo=us-smtp-delivery-1.mimecast.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/05/11 03:10:56 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, SPF_PASS=-0.001 autolearn=_AUTOLEARN X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Fam Zheng , =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= , Eduardo Habkost , "Michael S. Tsirkin" , Maxim Levitsky , Paolo Bonzini Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" Some code might race with placement of new devices on a bus. We currently first place a (unrealized) device on the bus and then realize it. As a workaround, users that scan the child device list, can check the realized property to see if it is safe to access such a device. Use an atomic write here too to aid with this. A separate discussion is what to do with devices that are unrealized: It looks like for this case we only call the hotplug handler's unplug callback and its up to it to unrealize the device. An atomic operation doesn't cause harm for this code path though. Signed-off-by: Maxim Levitsky --- hw/core/qdev.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/hw/core/qdev.c b/hw/core/qdev.c index 732789e2b7..d530c5922f 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -964,7 +964,20 @@ static void device_set_realized(Object *obj, bool value, Error **errp) } } + atomic_store_release(&dev->realized, value); + } else if (!value && dev->realized) { + + /* + * Change the value so that any concurrent users are aware + * that the device is going to be unrealized + * + * TODO: change .realized property to enum that states + * each phase of the device realization/unrealization + */ + + atomic_store_release(&dev->realized, value); + /* We want local_err to track only the first error */ QLIST_FOREACH(bus, &dev->child_bus, sibling) { object_property_set_bool(OBJECT(bus), false, "realized", @@ -980,12 +993,12 @@ static void device_set_realized(Object *obj, bool value, Error **errp) DEVICE_LISTENER_CALL(unrealize, Reverse, dev); if (local_err != NULL) { + atomic_store_release(&dev->realized, true); goto fail; } } assert(local_err == NULL); - dev->realized = value; return; child_realize_fail: From patchwork Mon May 11 16:09:49 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxim Levitsky X-Patchwork-Id: 11541267 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D376892A for ; Mon, 11 May 2020 16:13:21 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id A991D20714 for ; Mon, 11 May 2020 16:13:21 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="DB+6pskm" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org A991D20714 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:36986 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jYB3Q-0007fW-Od for patchwork-qemu-devel@patchwork.kernel.org; Mon, 11 May 2020 12:13:20 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:48270) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jYB0V-0002WR-9Q for qemu-devel@nongnu.org; Mon, 11 May 2020 12:10:19 -0400 Received: from us-smtp-1.mimecast.com ([205.139.110.61]:20573 helo=us-smtp-delivery-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1jYB0U-0001A1-CB for qemu-devel@nongnu.org; Mon, 11 May 2020 12:10:18 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1589213417; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:content-type:content-type:in-reply-to:in-reply-to: references:references; bh=v6NxqcYEzK4ft0LoCoTz3Wn4loJq3RbuOWoQob7rOWk=; b=DB+6pskmGNBwJ4kAMHELhA7DnK6CC0KPu1MIcZIVI+7QHj5Kf9V5wUUxqHszsvqMLd1x9n g+deqt6tdWZsGj/tUWbWOji/h+f2gPBXLIy1JkfbOnMjbnIhUzkxHU7Fj4eJ23/VlBN0Tt a5eNs6+5uJbWLu4jiSEwIm9xq/CDde4= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-60-2kxTre3wMHuXfFizGc1jaw-1; Mon, 11 May 2020 12:10:13 -0400 X-MC-Unique: 2kxTre3wMHuXfFizGc1jaw-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id ADA8B475; Mon, 11 May 2020 16:10:12 +0000 (UTC) Received: from maximlenovopc.usersys.redhat.com (unknown [10.35.206.222]) by smtp.corp.redhat.com (Postfix) with ESMTP id C746A5C1B5; Mon, 11 May 2020 16:10:10 +0000 (UTC) From: Maxim Levitsky To: qemu-devel@nongnu.org Subject: [PATCH v2 5/7] virtio-scsi: don't touch scsi devices that are not yet realized or about to be un-realized Date: Mon, 11 May 2020 19:09:49 +0300 Message-Id: <20200511160951.8733-6-mlevitsk@redhat.com> In-Reply-To: <20200511160951.8733-1-mlevitsk@redhat.com> References: <20200511160951.8733-1-mlevitsk@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=205.139.110.61; envelope-from=mlevitsk@redhat.com; helo=us-smtp-delivery-1.mimecast.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/05/11 03:10:56 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, SPF_PASS=-0.001 autolearn=_AUTOLEARN X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Fam Zheng , =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= , Eduardo Habkost , "Michael S. Tsirkin" , Maxim Levitsky , Paolo Bonzini Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1812399 Suggested-by: Paolo Bonzini Signed-off-by: Maxim Levitsky Reviewed-by: Stefan Hajnoczi --- hw/scsi/virtio-scsi.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c index b0f4a35f81..1cc1fc557c 100644 --- a/hw/scsi/virtio-scsi.c +++ b/hw/scsi/virtio-scsi.c @@ -35,13 +35,30 @@ static inline int virtio_scsi_get_lun(uint8_t *lun) static inline SCSIDevice *virtio_scsi_device_find(VirtIOSCSI *s, uint8_t *lun) { + SCSIDevice *device = NULL; + if (lun[0] != 1) { return NULL; } if (lun[2] != 0 && !(lun[2] >= 0x40 && lun[2] < 0x80)) { return NULL; } - return scsi_device_find(&s->bus, 0, lun[1], virtio_scsi_get_lun(lun)); + + device = scsi_device_find(&s->bus, 0, lun[1], virtio_scsi_get_lun(lun)); + + /* + * This function might run on the IO thread and we might race against + * main thread hot-plugging the device. + * + * We assume that as soon as .realized is set to true we can let + * the user access the device. + */ + + if (!device || !atomic_load_acquire(&device->qdev.realized)) { + return NULL; + } + + return device; } void virtio_scsi_init_req(VirtIOSCSI *s, VirtQueue *vq, VirtIOSCSIReq *req) From patchwork Mon May 11 16:09:50 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxim Levitsky X-Patchwork-Id: 11541273 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0981D139A for ; Mon, 11 May 2020 16:15:55 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id D23B4206DB for ; Mon, 11 May 2020 16:15:54 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="SYuK8AxG" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org D23B4206DB Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:44776 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jYB5u-00037p-1i for patchwork-qemu-devel@patchwork.kernel.org; Mon, 11 May 2020 12:15:54 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:48280) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jYB0Y-0002er-Px for qemu-devel@nongnu.org; Mon, 11 May 2020 12:10:22 -0400 Received: from us-smtp-1.mimecast.com ([207.211.31.81]:56920 helo=us-smtp-delivery-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1jYB0X-0001Cq-Tp for qemu-devel@nongnu.org; Mon, 11 May 2020 12:10:22 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1589213421; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:content-type:content-type:in-reply-to:in-reply-to: references:references; bh=z6E8fClkSbbsupJYLxw1Lqcf48MNwJNj/0CvVbP4DbE=; b=SYuK8AxGhlkjdVuQNFTjQSYRmvC+K5U/ZZ77QzeduoQdAbrdjTAmBFAgreDyI73A6GUQKi 00+f7YJxiarUN4pH3kOlzdzOBmuHnrbhS7qshbSHFWKvH3fENhKEqSD76XsEYOpvTTISoP nFuVRawGJm5L8tAxa29szB+GelFu60o= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-505-0Ei92VfpP_aD3WJP1FHoYA-1; Mon, 11 May 2020 12:10:18 -0400 X-MC-Unique: 0Ei92VfpP_aD3WJP1FHoYA-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id E7350A0BE1; Mon, 11 May 2020 16:10:17 +0000 (UTC) Received: from maximlenovopc.usersys.redhat.com (unknown [10.35.206.222]) by smtp.corp.redhat.com (Postfix) with ESMTP id 1AC4A5C1B5; Mon, 11 May 2020 16:10:12 +0000 (UTC) From: Maxim Levitsky To: qemu-devel@nongnu.org Subject: [PATCH v2 6/7] scsi: Add scsi_device_get Date: Mon, 11 May 2020 19:09:50 +0300 Message-Id: <20200511160951.8733-7-mlevitsk@redhat.com> In-Reply-To: <20200511160951.8733-1-mlevitsk@redhat.com> References: <20200511160951.8733-1-mlevitsk@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=207.211.31.81; envelope-from=mlevitsk@redhat.com; helo=us-smtp-delivery-1.mimecast.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/05/11 01:43:51 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] [fuzzy] X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, SPF_PASS=-0.001 autolearn=_AUTOLEARN X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Fam Zheng , =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= , Eduardo Habkost , "Michael S. Tsirkin" , Maxim Levitsky , Paolo Bonzini Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" Add scsi_device_get which finds the scsi device and takes a reference to it. Suggested-by: Stefan Hajnoczi Signed-off-by: Maxim Levitsky --- hw/scsi/scsi-bus.c | 31 ++++++++++++++++++++++++------- include/hw/scsi/scsi.h | 2 ++ 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c index 2bf6d005f3..4e15de0bd7 100644 --- a/hw/scsi/scsi-bus.c +++ b/hw/scsi/scsi-bus.c @@ -1584,8 +1584,13 @@ static char *scsibus_get_fw_dev_path(DeviceState *dev) return g_strdup_printf("channel@%x/%s@%x,%x", d->channel, qdev_fw_name(dev), d->id, d->lun); } - -SCSIDevice *scsi_device_find(SCSIBus *bus, int channel, int id, int lun) +/* + * Finds a matching channel/id/lun device on scsi bus, and + * takes a reference to it and returns it. + * If we don't find exact match (channel/bus/lun), + * we will return the first device which matches channel/bus + * */ +SCSIDevice *scsi_device_get(SCSIBus *bus, int channel, int id, int lun) { BusChild *kid; SCSIDevice *target_dev = NULL; @@ -1598,25 +1603,37 @@ SCSIDevice *scsi_device_find(SCSIBus *bus, int channel, int id, int lun) if (dev->channel == channel && dev->id == id) { if (dev->lun == lun) { + object_ref(OBJECT(dev)); rcu_read_unlock(); return dev; } - /* - * If we don't find exact match (channel/bus/lun), - * we will return the first device which matches channel/bus - */ - if (!target_dev) { target_dev = dev; } } } + object_ref(OBJECT(target_dev)); rcu_read_unlock(); return target_dev; } +/* + * This function works like scsi_device_get but doesn't take a refernce + * to the returned object. Intended for legacy code + */ +SCSIDevice *scsi_device_find(SCSIBus *bus, int channel, int id, int lun) +{ + SCSIDevice *dev = scsi_device_get(bus, channel, id, lun); + + if (!dev) + return NULL; + + object_unref(OBJECT(dev)); + return dev; +} + /* SCSI request list. For simplicity, pv points to the whole device */ static int put_scsi_requests(QEMUFile *f, void *pv, size_t size, diff --git a/include/hw/scsi/scsi.h b/include/hw/scsi/scsi.h index 332ef602f4..5e1d31ab6d 100644 --- a/include/hw/scsi/scsi.h +++ b/include/hw/scsi/scsi.h @@ -193,7 +193,9 @@ void scsi_generic_read_device_inquiry(SCSIDevice *dev); int scsi_device_get_sense(SCSIDevice *dev, uint8_t *buf, int len, bool fixed); int scsi_SG_IO_FROM_DEV(BlockBackend *blk, uint8_t *cmd, uint8_t cmd_size, uint8_t *buf, uint8_t buf_size); + SCSIDevice *scsi_device_find(SCSIBus *bus, int channel, int target, int lun); +SCSIDevice *scsi_device_get(SCSIBus *bus, int channel, int target, int lun); /* scsi-generic.c. */ extern const SCSIReqOps scsi_generic_req_ops; From patchwork Mon May 11 16:09:51 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxim Levitsky X-Patchwork-Id: 11541271 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id ACB52139A for ; Mon, 11 May 2020 16:15:17 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 81DBC206DB for ; Mon, 11 May 2020 16:15:17 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="THrdzC7u" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 81DBC206DB Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:43328 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jYB5I-0002R9-O4 for patchwork-qemu-devel@patchwork.kernel.org; Mon, 11 May 2020 12:15:16 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:48284) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jYB0a-0002iI-E2 for qemu-devel@nongnu.org; Mon, 11 May 2020 12:10:24 -0400 Received: from us-smtp-delivery-1.mimecast.com ([207.211.31.120]:42205 helo=us-smtp-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1jYB0Z-0001DK-FQ for qemu-devel@nongnu.org; Mon, 11 May 2020 12:10:24 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1589213422; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:content-type:content-type:in-reply-to:in-reply-to: references:references; bh=M2bq9zCzPz6VKGeh8nVA6yikaTYR6Kt0Jgibe/QpFOE=; b=THrdzC7uFsnu2D6w9HMnXMtr/OdARVwk1IIXcPk2gyOkhaBxlQ/9TWJ0VdwhlpKQxyvKXN z+mda67byFyBKSQbvvP1SRMHv9bQ1jSkYNBUhgBS9EiNuEvoXhaAw7IQPHiYkwoNsNy0gR CO55gmeBxK6knIT/hrUSupLkTDz3fxM= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-115-OLzwoMF6PqyuB0Axg2y-4w-1; Mon, 11 May 2020 12:10:21 -0400 X-MC-Unique: OLzwoMF6PqyuB0Axg2y-4w-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 3B04180B725; Mon, 11 May 2020 16:10:20 +0000 (UTC) Received: from maximlenovopc.usersys.redhat.com (unknown [10.35.206.222]) by smtp.corp.redhat.com (Postfix) with ESMTP id 541EA5C1B5; Mon, 11 May 2020 16:10:18 +0000 (UTC) From: Maxim Levitsky To: qemu-devel@nongnu.org Subject: [PATCH v2 7/7] virtio-scsi: use scsi_device_get Date: Mon, 11 May 2020 19:09:51 +0300 Message-Id: <20200511160951.8733-8-mlevitsk@redhat.com> In-Reply-To: <20200511160951.8733-1-mlevitsk@redhat.com> References: <20200511160951.8733-1-mlevitsk@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=207.211.31.120; envelope-from=mlevitsk@redhat.com; helo=us-smtp-1.mimecast.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/05/11 02:55:57 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] [fuzzy] X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, SPF_PASS=-0.001 autolearn=_AUTOLEARN X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Fam Zheng , =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= , Eduardo Habkost , "Michael S. Tsirkin" , Maxim Levitsky , Paolo Bonzini Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" This will help us to avoid the scsi device disappearing after we took a reference to it. It doesn't by itself forbid case when we try to access an unrealized device Suggested-by: Stefan Hajnoczi Signed-off-by: Maxim Levitsky Reviewed-by: Stefan Hajnoczi --- hw/scsi/virtio-scsi.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c index 1cc1fc557c..65cd4186fe 100644 --- a/hw/scsi/virtio-scsi.c +++ b/hw/scsi/virtio-scsi.c @@ -33,7 +33,7 @@ static inline int virtio_scsi_get_lun(uint8_t *lun) return ((lun[2] << 8) | lun[3]) & 0x3FFF; } -static inline SCSIDevice *virtio_scsi_device_find(VirtIOSCSI *s, uint8_t *lun) +static inline SCSIDevice *virtio_scsi_device_get(VirtIOSCSI *s, uint8_t *lun) { SCSIDevice *device = NULL; @@ -44,7 +44,7 @@ static inline SCSIDevice *virtio_scsi_device_find(VirtIOSCSI *s, uint8_t *lun) return NULL; } - device = scsi_device_find(&s->bus, 0, lun[1], virtio_scsi_get_lun(lun)); + device = scsi_device_get(&s->bus, 0, lun[1], virtio_scsi_get_lun(lun)); /* * This function might run on the IO thread and we might race against @@ -61,6 +61,8 @@ static inline SCSIDevice *virtio_scsi_device_find(VirtIOSCSI *s, uint8_t *lun) return device; } + + void virtio_scsi_init_req(VirtIOSCSI *s, VirtQueue *vq, VirtIOSCSIReq *req) { VirtIODevice *vdev = VIRTIO_DEVICE(s); @@ -273,7 +275,7 @@ static inline void virtio_scsi_ctx_check(VirtIOSCSI *s, SCSIDevice *d) * case of async cancellation. */ static int virtio_scsi_do_tmf(VirtIOSCSI *s, VirtIOSCSIReq *req) { - SCSIDevice *d = virtio_scsi_device_find(s, req->req.tmf.lun); + SCSIDevice *d = virtio_scsi_device_get(s, req->req.tmf.lun); SCSIRequest *r, *next; BusChild *kid; int target; @@ -387,10 +389,10 @@ static int virtio_scsi_do_tmf(VirtIOSCSI *s, VirtIOSCSIReq *req) rcu_read_lock(); QTAILQ_FOREACH_RCU(kid, &s->bus.qbus.children, sibling) { - d = SCSI_DEVICE(kid->child); - if (d->channel == 0 && d->id == target) { - qdev_reset_all(&d->qdev); - } + SCSIDevice *d1 = SCSI_DEVICE(kid->child); + if (d1->channel == 0 && d1->id == target) { + qdev_reset_all(&d1->qdev); + } } rcu_read_unlock(); @@ -403,14 +405,17 @@ static int virtio_scsi_do_tmf(VirtIOSCSI *s, VirtIOSCSIReq *req) break; } + object_unref(OBJECT(d)); return ret; incorrect_lun: req->resp.tmf.response = VIRTIO_SCSI_S_INCORRECT_LUN; + object_unref(OBJECT(d)); return ret; fail: req->resp.tmf.response = VIRTIO_SCSI_S_BAD_TARGET; + object_unref(OBJECT(d)); return ret; } @@ -581,7 +586,7 @@ static int virtio_scsi_handle_cmd_req_prepare(VirtIOSCSI *s, VirtIOSCSIReq *req) } } - d = virtio_scsi_device_find(s, req->req.cmd.lun); + d = virtio_scsi_device_get(s, req->req.cmd.lun); if (!d) { req->resp.cmd.response = VIRTIO_SCSI_S_BAD_TARGET; virtio_scsi_complete_cmd_req(req); @@ -597,10 +602,12 @@ static int virtio_scsi_handle_cmd_req_prepare(VirtIOSCSI *s, VirtIOSCSIReq *req) req->sreq->cmd.xfer > req->qsgl.size)) { req->resp.cmd.response = VIRTIO_SCSI_S_OVERRUN; virtio_scsi_complete_cmd_req(req); + object_unref(OBJECT(d)); return -ENOBUFS; } scsi_req_ref(req->sreq); blk_io_plug(d->conf.blk); + object_unref(OBJECT(d)); return 0; }