From patchwork Fri Aug 16 13:22:06 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 819740 Delivered-To: patch@linaro.org Received: by 2002:adf:a3c8:0:b0:367:895a:4699 with SMTP id m8csp286979wrb; Fri, 16 Aug 2024 06:24:20 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCWpIP3LMqOOLPhfvV88RPMtcPWyTvrlFJV0z6SDIaDYHj13A7RbLIZdDdm8GlpfI3FYZ/kHHAbQ8C4V2OjqZU2t X-Google-Smtp-Source: AGHT+IEMwZcK2Cb1HmcAofSTAF0/jki9LCc+w1/QxqvTwV33wDjp7KMWcAa1LWM+SqaYiyTNDvTD X-Received: by 2002:a05:6359:5a92:b0:1aa:a01a:23dc with SMTP id e5c5f4694b2df-1b3931b8c6amr400184055d.15.1723814660404; Fri, 16 Aug 2024 06:24:20 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1723814660; cv=none; d=google.com; s=arc-20160816; b=VsfqdNFfGC6XigSUTpV8m9l7855udFuDWkhtZbjjPHvJtyOMfvXUxYFV3DOsm3Wig2 REP55m4cv7mvZlr5BE2za4zaYBriOM+O+oKqhHp4rPo33Cdu4UBUnZysazqpudwnXdX1 3AwDE1WnvXcX4fyt/qEhSd3CnOBNO0dpAgYA78h/qTSRPTEqMqdn4V+U0jjxFbalpRWw 0xTnp56FN/EOnIU4Xqz+EQorhqu0XfipAgooAZlmIoUMezNtP16WgTgl0OHswFiNAJLG jZs9rXk1VD16WI6xOquPTT3E5VfNEHMbgLBqOsWP16etcAtScb0Ht0y3LBCeu2kLyFbQ Z2MA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=+qDfeY+CsvBUJu7CFKOtFh4EY2RJKFqnGcNsx1NoFx4=; fh=NVInRNxxVvpKCXHA+YUXRIpSUGsR0gcBKdN/9cCMaL0=; b=lfrpjulrEEVpdUYj2WW1Uhy+fRktHc4ysYsoOeDVS2PJX5DihLTYGdl19r9enHh+ja E8VZq2oozfmamHih2jKWwXs2cLZGa8ReKDy2nleuSu2VO4jq13s5BFED3tLrVeLFzzFJ nebSTOtSKyGseJNOfVj9sa5HXlQkc5IA90ReHG4adyb1x8LpnbbBP1934G3/1xUMDLD3 +IqLoQD0eQ0MpiHAT21xcm6Q56fTfRj2+hWZAoCuCnjGivds0mO0FPpENJwpIDhaV/mi IxdMikI8UCpa44pIDeDtUZS+cXdzQilaOky4HDX8u7CROtOe/Uxoqi+sYpwHhc1zZSwF UyJQ==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="lLNr/K3Q"; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org; dara=neutral header.i=@linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id 6a1803df08f44-6bf6fdc696dsi42050016d6.9.2024.08.16.06.24.20 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Fri, 16 Aug 2024 06:24:20 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="lLNr/K3Q"; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org; dara=neutral header.i=@linaro.org Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sewuQ-0005Qt-Bl; Fri, 16 Aug 2024 09:22:26 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sewuK-000597-MC for qemu-devel@nongnu.org; Fri, 16 Aug 2024 09:22:20 -0400 Received: from mail-wm1-x333.google.com ([2a00:1450:4864:20::333]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1sewuH-0007k0-7k for qemu-devel@nongnu.org; Fri, 16 Aug 2024 09:22:20 -0400 Received: by mail-wm1-x333.google.com with SMTP id 5b1f17b1804b1-4281faefea9so13831155e9.2 for ; Fri, 16 Aug 2024 06:22:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1723814535; x=1724419335; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=+qDfeY+CsvBUJu7CFKOtFh4EY2RJKFqnGcNsx1NoFx4=; b=lLNr/K3QeQ7ARwo1nnHRnMBfEQlxaklE85pxr8pvnjvvy0uZlsI2XHCHNi5rqmc86v p4ptX5iUDU8y/GQCngm2GnnwyZmOiPWadrhUVJGaUHHno/luJ/sJ3fUsRjGChozwydLD MyN128P2EfL0W0LC8vNr/kJenDTHv9nkjHzKGr5BnyG0B2iXz2oJQVQA8psXcSYwTXj/ 6Z4c0RENxm3JZDf4cRZq/a7SpDECAVjU2O86xi4xguqwTQd0KWt9trH9/5QCOptAGbtl dvNx0Y+xp+JlAvC9EJccwazEAdxZ1VVEt5Z9huS7qVMCGP0aFU+I+z6oMehyRbzpDQZr cNRw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1723814535; x=1724419335; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=+qDfeY+CsvBUJu7CFKOtFh4EY2RJKFqnGcNsx1NoFx4=; b=Fs9w4JpsAhfSIa7Za3XiRkl3gjuOyRScIrtFqbREsRONZrP6TcYBlOoxXI2uET2/ig acM17I7StlfIg97E339aWQR2wjepxPf9l78fPXu3rtVS6yd63wYKDb8EqUkLqlarDqrV N7DLyH9puCmimVEQWgm3p2Zms3cslBvPzclI3Uc+6e2e8pVctLdC5DDFhlcz97Z/qOZV 38HDrvSwCHhJosrDTcmfqvjpK6zKtaGvbN/ruxBjTHPgEAhtbDeeNxQ2QjKz8oBmchiP J+LblCfevi3b39KVfTJA7kshQp3wAsK0j+LILJ/qpcTZlJYAL5cRkMJAbj9ZKseuGLct z50A== X-Gm-Message-State: AOJu0YzwZvsPEY3lWPuYlBJG/XDefxLerisb9lKMwBfqv88OB1yxQGLI ggOXBRPCAxSF1p8BJ6TMcSQfwJwAOCX/QSvNi+QSDlhK6o5EKlXnqgrQwMNWPu7rtY3UlP3lz1k Y X-Received: by 2002:adf:ef4b:0:b0:368:3ee5:e3e1 with SMTP id ffacd0b85a97d-37194314e6emr2086023f8f.7.1723814534888; Fri, 16 Aug 2024 06:22:14 -0700 (PDT) Received: from orth.archaic.org.uk (orth.archaic.org.uk. [2001:8b0:1d0::2]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-371898ab855sm3631948f8f.105.2024.08.16.06.22.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 16 Aug 2024 06:22:14 -0700 (PDT) From: Peter Maydell To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Kevin Wolf , Hanna Reitz , Stefan Hajnoczi Subject: [PATCH 1/7] docs/devel/blkdebug: Convert to rST format Date: Fri, 16 Aug 2024 14:22:06 +0100 Message-Id: <20240816132212.3602106-2-peter.maydell@linaro.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240816132212.3602106-1-peter.maydell@linaro.org> References: <20240816132212.3602106-1-peter.maydell@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::333; envelope-from=peter.maydell@linaro.org; helo=mail-wm1-x333.google.com 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, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: qemu-devel-bounces+patch=linaro.org@nongnu.org Convert blkdebug.txt to rST format. We put it into index-build.rst because it falls under the "test" part of "QEMU Build and Test System". Signed-off-by: Peter Maydell Reviewed-by: Thomas Huth --- At least, index-build seemed the most plausible home to me... --- MAINTAINERS | 1 + docs/devel/blkdebug.rst | 177 +++++++++++++++++++++++++++++++++++++ docs/devel/blkdebug.txt | 162 --------------------------------- docs/devel/index-build.rst | 1 + 4 files changed, 179 insertions(+), 162 deletions(-) create mode 100644 docs/devel/blkdebug.rst delete mode 100644 docs/devel/blkdebug.txt diff --git a/MAINTAINERS b/MAINTAINERS index 3584d6a6c6d..ca0a5c731f5 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4015,6 +4015,7 @@ M: Hanna Reitz L: qemu-block@nongnu.org S: Supported F: block/blkdebug.c +F: docs/devel/blkdebug.rst vpc M: Kevin Wolf diff --git a/docs/devel/blkdebug.rst b/docs/devel/blkdebug.rst new file mode 100644 index 00000000000..63887c9aa9c --- /dev/null +++ b/docs/devel/blkdebug.rst @@ -0,0 +1,177 @@ +Block I/O error injection using ``blkdebug`` +============================================ + +.. + Copyright (C) 2014-2015 Red Hat Inc + + This work is licensed under the terms of the GNU GPL, version 2 or later. See + the COPYING file in the top-level directory. + +The ``blkdebug`` block driver is a rule-based error injection engine. It can be +used to exercise error code paths in block drivers including ``ENOSPC`` (out of +space) and ``EIO``. + +This document gives an overview of the features available in ``blkdebug``. + +Background +---------- +Block drivers have many error code paths that handle I/O errors. Image formats +are especially complex since metadata I/O errors during cluster allocation or +while updating tables happen halfway through request processing and require +discipline to keep image files consistent. + +Error injection allows test cases to trigger I/O errors at specific points. +This way, all error paths can be tested to make sure they are correct. + +Rules +----- +The ``blkdebug`` block driver takes a list of "rules" that tell the error injection +engine when to fail an I/O request. + +Each I/O request is evaluated against the rules. If a rule matches the request +then its "action" is executed. + +Rules can be placed in a configuration file; the configuration file +follows the same .ini-like format used by QEMU's ``-readconfig`` option, and +each section of the file represents a rule. + +The following configuration file defines a single rule:: + + $ cat blkdebug.conf + [inject-error] + event = "read_aio" + errno = "28" + +This rule fails all aio read requests with ``ENOSPC`` (28). Note that the errno +value depends on the host. On Linux, see +``/usr/include/asm-generic/errno-base.h`` for errno values. + +Invoke QEMU as follows:: + + $ qemu-system-x86_64 + -drive if=none,cache=none,file=blkdebug:blkdebug.conf:test.img,id=drive0 \ + -device virtio-blk-pci,drive=drive0,id=virtio-blk-pci0 + +Rules support the following attributes: + +``event`` + which type of operation to match (e.g. ``read_aio``, ``write_aio``, + ``flush_to_os``, ``flush_to_disk``). See `Events`_ for + information on events. + +``state`` + (optional) the engine must be in this state number in order for this + rule to match. See `State transitions`_ for information + on states. + +``errno`` + the numeric errno value to return when a request matches this rule. + The errno values depend on the host since the numeric values are not + standardized in the POSIX specification. + +``sector`` + (optional) a sector number that the request must overlap in order to + match this rule + +``once`` + (optional, default ``off``) only execute this action on the first + matching request + +``immediately`` + (optional, default ``off``) return a NULL ``BlockAIOCB`` + pointer and fail without an errno instead. This + exercises the code path where ``BlockAIOCB`` fails and the + caller's ``BlockCompletionFunc`` is not invoked. + +Events +------ +Block drivers provide information about the type of I/O request they are about +to make so rules can match specific types of requests. For example, the ``qcow2`` +block driver tells ``blkdebug`` when it accesses the L1 table so rules can match +only L1 table accesses and not other metadata or guest data requests. + +The core events are: + +``read_aio`` + guest data read + +``write_aio`` + guest data write + +``flush_to_os`` + write out unwritten block driver state (e.g. cached metadata) + +``flush_to_disk`` + flush the host block device's disk cache + +See ``qapi/block-core.json:BlkdebugEvent`` for the full list of events. +You may need to grep block driver source code to understand the +meaning of specific events. + +State transitions +----------------- +There are cases where more power is needed to match a particular I/O request in +a longer sequence of requests. For example:: + + write_aio + flush_to_disk + write_aio + +How do we match the 2nd ``write_aio`` but not the first? This is where state +transitions come in. + +The error injection engine has an integer called the "state" that always starts +initialized to 1. The state integer is internal to ``blkdebug`` and cannot be +observed from outside but rules can interact with it for powerful matching +behavior. + +Rules can be conditional on the current state and they can transition to a new +state. + +When a rule's "state" attribute is non-zero then the current state must equal +the attribute in order for the rule to match. + +For example, to match the 2nd write_aio:: + + [set-state] + event = "write_aio" + state = "1" + new_state = "2" + + [inject-error] + event = "write_aio" + state = "2" + errno = "5" + +The first ``write_aio`` request matches the ``set-state`` rule and transitions from +state 1 to state 2. Once state 2 has been entered, the ``set-state`` rule no +longer matches since it requires state 1. But the ``inject-error`` rule now +matches the next ``write_aio`` request and injects ``EIO`` (5). + +State transition rules support the following attributes: + +``event`` + which type of operation to match (e.g. ``read_aio``, ``write_aio``, + ``flush_to_os`, ``flush_to_disk``). See `Events`_ for + information on events. + +``state`` + (optional) the engine must be in this state number in order for this + rule to match + +``new_state`` + transition to this state number + +Suspend and resume +------------------ +Exercising code paths in block drivers may require specific ordering amongst +concurrent requests. The "breakpoint" feature allows requests to be halted on +a ``blkdebug`` event and resumed later. This makes it possible to achieve +deterministic ordering when multiple requests are in flight. + +Breakpoints on ``blkdebug`` events are associated with a user-defined ``tag`` string. +This tag serves as an identifier by which the request can be resumed at a later +point. + +See the ``qemu-io(1)`` ``break``, ``resume``, ``remove_break``, and ``wait_break`` +commands for details. diff --git a/docs/devel/blkdebug.txt b/docs/devel/blkdebug.txt deleted file mode 100644 index 0b0c128d356..00000000000 --- a/docs/devel/blkdebug.txt +++ /dev/null @@ -1,162 +0,0 @@ -Block I/O error injection using blkdebug ----------------------------------------- -Copyright (C) 2014-2015 Red Hat Inc - -This work is licensed under the terms of the GNU GPL, version 2 or later. See -the COPYING file in the top-level directory. - -The blkdebug block driver is a rule-based error injection engine. It can be -used to exercise error code paths in block drivers including ENOSPC (out of -space) and EIO. - -This document gives an overview of the features available in blkdebug. - -Background ----------- -Block drivers have many error code paths that handle I/O errors. Image formats -are especially complex since metadata I/O errors during cluster allocation or -while updating tables happen halfway through request processing and require -discipline to keep image files consistent. - -Error injection allows test cases to trigger I/O errors at specific points. -This way, all error paths can be tested to make sure they are correct. - -Rules ------ -The blkdebug block driver takes a list of "rules" that tell the error injection -engine when to fail an I/O request. - -Each I/O request is evaluated against the rules. If a rule matches the request -then its "action" is executed. - -Rules can be placed in a configuration file; the configuration file -follows the same .ini-like format used by QEMU's -readconfig option, and -each section of the file represents a rule. - -The following configuration file defines a single rule: - - $ cat blkdebug.conf - [inject-error] - event = "read_aio" - errno = "28" - -This rule fails all aio read requests with ENOSPC (28). Note that the errno -value depends on the host. On Linux, see -/usr/include/asm-generic/errno-base.h for errno values. - -Invoke QEMU as follows: - - $ qemu-system-x86_64 - -drive if=none,cache=none,file=blkdebug:blkdebug.conf:test.img,id=drive0 \ - -device virtio-blk-pci,drive=drive0,id=virtio-blk-pci0 - -Rules support the following attributes: - - event - which type of operation to match (e.g. read_aio, write_aio, - flush_to_os, flush_to_disk). See the "Events" section for - information on events. - - state - (optional) the engine must be in this state number in order for this - rule to match. See the "State transitions" section for information - on states. - - errno - the numeric errno value to return when a request matches this rule. - The errno values depend on the host since the numeric values are not - standardized in the POSIX specification. - - sector - (optional) a sector number that the request must overlap in order to - match this rule - - once - (optional, default "off") only execute this action on the first - matching request - - immediately - (optional, default "off") return a NULL BlockAIOCB - pointer and fail without an errno instead. This - exercises the code path where BlockAIOCB fails and the - caller's BlockCompletionFunc is not invoked. - -Events ------- -Block drivers provide information about the type of I/O request they are about -to make so rules can match specific types of requests. For example, the qcow2 -block driver tells blkdebug when it accesses the L1 table so rules can match -only L1 table accesses and not other metadata or guest data requests. - -The core events are: - - read_aio - guest data read - - write_aio - guest data write - - flush_to_os - write out unwritten block driver state (e.g. cached metadata) - - flush_to_disk - flush the host block device's disk cache - -See qapi/block-core.json:BlkdebugEvent for the full list of events. -You may need to grep block driver source code to understand the -meaning of specific events. - -State transitions ------------------ -There are cases where more power is needed to match a particular I/O request in -a longer sequence of requests. For example: - - write_aio - flush_to_disk - write_aio - -How do we match the 2nd write_aio but not the first? This is where state -transitions come in. - -The error injection engine has an integer called the "state" that always starts -initialized to 1. The state integer is internal to blkdebug and cannot be -observed from outside but rules can interact with it for powerful matching -behavior. - -Rules can be conditional on the current state and they can transition to a new -state. - -When a rule's "state" attribute is non-zero then the current state must equal -the attribute in order for the rule to match. - -For example, to match the 2nd write_aio: - - [set-state] - event = "write_aio" - state = "1" - new_state = "2" - - [inject-error] - event = "write_aio" - state = "2" - errno = "5" - -The first write_aio request matches the set-state rule and transitions from -state 1 to state 2. Once state 2 has been entered, the set-state rule no -longer matches since it requires state 1. But the inject-error rule now -matches the next write_aio request and injects EIO (5). - -State transition rules support the following attributes: - - event - which type of operation to match (e.g. read_aio, write_aio, - flush_to_os, flush_to_disk). See the "Events" section for - information on events. - - state - (optional) the engine must be in this state number in order for this - rule to match - - new_state - transition to this state number - -Suspend and resume ------------------- -Exercising code paths in block drivers may require specific ordering amongst -concurrent requests. The "breakpoint" feature allows requests to be halted on -a blkdebug event and resumed later. This makes it possible to achieve -deterministic ordering when multiple requests are in flight. - -Breakpoints on blkdebug events are associated with a user-defined "tag" string. -This tag serves as an identifier by which the request can be resumed at a later -point. - -See the qemu-io(1) break, resume, remove_break, and wait_break commands for -details. diff --git a/docs/devel/index-build.rst b/docs/devel/index-build.rst index 90b406ca0ed..3a912aefcfa 100644 --- a/docs/devel/index-build.rst +++ b/docs/devel/index-build.rst @@ -18,3 +18,4 @@ the basics if you are adding new files and targets to the build. qapi-code-gen fuzzing control-flow-integrity + blkdebug From patchwork Fri Aug 16 13:22:07 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 819733 Delivered-To: patch@linaro.org Received: by 2002:adf:a3c8:0:b0:367:895a:4699 with SMTP id m8csp286045wrb; Fri, 16 Aug 2024 06:22:47 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCUBHxn7fdH9vGE8ryYsf79vIBkm8qgQMcuZp+at4T6zn6ASHjqaXuavvYPxHE40j49/z5BlNA==@linaro.org X-Google-Smtp-Source: AGHT+IEg1WhbITgFdVEQ9dj52fq5uqPwdn/0bWdbXihIik/XMIqQdRHWuVD+r4Z2lJpjW/BAw76Z X-Received: by 2002:a05:6358:9890:b0:1ad:1d18:dc2a with SMTP id e5c5f4694b2df-1b3931a57a1mr378504555d.12.1723814567378; Fri, 16 Aug 2024 06:22:47 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1723814567; cv=none; d=google.com; s=arc-20160816; b=yCO9uQk7iAk3SkkWDiQMUjBmhKsL35No87Yp0tyZaXKy9BvvY8dUrX8UKSIM5SwEyi WaS0x4E2bmE/69PL6hxaMrqVzznDBoMYW0/kUCZ8dSEXXLQz6ROTEGcb2xXMrMr7FNhw m8+hBQnODk615v0uIqoFnX9/+x5fI56X+tNK7vBinP6tGXh24l6B2ddArOoKzKR88TpO AOCYdR7bhHQp4u3fM0BIM1Bg5eid67ZAdB8F3TxZSMKzE8hJdITaSnwWHTn7CRKJtV8Q G8keXV++jqS/nHKaLZ2/y5NStbZKccSC8SwTtv+TrxpGzS9QNGd2Q1q6p43u7DKvzcy/ ssZQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=L3BYyoFuiUhi097Go1IdQzbbTPVpAV8zdtNg6dApNEU=; fh=NVInRNxxVvpKCXHA+YUXRIpSUGsR0gcBKdN/9cCMaL0=; b=ivzMSbygzqUdXfvT/75Z2SdHoRNhlkXiSf+YZ/XYpyNScb1Wp4q5mTa6zU4W22qtms Ak29v4PzstY2vLbY05FYgMeUmz66Ym6/0TJcY4ZoQf7/bdi4mmkFpZS06yD46ZmUvhFb dxUq0JvdVotUMn3yVvjGi6otgG6Tz7VlnTWvZ+nSMMMFUD+4pAKWZib5534VfjLkenTp So3xxKNBkMl5v/C55KqTiHVI11upr1XCorP4IDL55Kjk1WWifVGJU3GQhA3kpHBeWoLf EiyFEF55m5zPj62lBMRtb6sBGHxv6AX6cxvEEXsnQfAmgm1uslO3LDbXELH8aruht/ZU DUhw==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=J0EN+EmQ; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org; dara=neutral header.i=@linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id af79cd13be357-7a6496276b2si53492885a.261.2024.08.16.06.22.47 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Fri, 16 Aug 2024 06:22:47 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=J0EN+EmQ; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org; dara=neutral header.i=@linaro.org Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sewuL-0005AY-T5; Fri, 16 Aug 2024 09:22:21 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sewuK-00058M-9g for qemu-devel@nongnu.org; Fri, 16 Aug 2024 09:22:20 -0400 Received: from mail-wr1-x42d.google.com ([2a00:1450:4864:20::42d]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1sewuH-0007k3-FK for qemu-devel@nongnu.org; Fri, 16 Aug 2024 09:22:19 -0400 Received: by mail-wr1-x42d.google.com with SMTP id ffacd0b85a97d-3719753d365so329409f8f.2 for ; Fri, 16 Aug 2024 06:22:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1723814535; x=1724419335; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=L3BYyoFuiUhi097Go1IdQzbbTPVpAV8zdtNg6dApNEU=; b=J0EN+EmQx8V2LrNaxrckjspv+g/23rnQZw0XXM15V7rrJM1uKtjTKi/X0JW9vLmGel pfcxbAh2e1Ye0xxX4wqr2GyfhR8HOCR8xlQWgmBEV06B6UzkuhAQTGv1Y0MRWymgs/V0 BILz2Cq9Qor3obJomOx7U1vVE9oXoYScFlFVCji6Enpb6esIvHcWvf5x2HbdN8phLndy 8Awz6qsOMR959WUHAblHDIPE8W/iqwh+fZM9nKuYDFGlOxypx9Auvcb/uLqscNw3BELN qlgN93+Sxpi27tOcKaCldafuXaII1GVBEXRSMDKNGJUvwKfR+i97n4uxIoXQE4SD+Aka kQfw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1723814535; x=1724419335; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=L3BYyoFuiUhi097Go1IdQzbbTPVpAV8zdtNg6dApNEU=; b=TAX0y+tE7HDNwvEkpOcL7ylYGZ7pEOdElBzqnc0LcjsYrtX+AtJihpkg/gaKtDt8mx aAYnvI2f0URi2jqT1heQOrxDi/nw9oHPeJnseAAoRV3Qql+2kc4NrdnxkKC4huFXhQ3H Xp8pvxwDqrzfIpD1lLi3LROrJqNRcObjcKuX1Fe5HCiUEhS46oDJoNW+OwG9tAW2iH5f TBvIkci5C32c4o8uX0Fo0EHoWL5sBV5lHSYZomFP3WimZgj4M/mY1q2FSQBVSYmqAMcK g1N7wlkslDQbEEenJSW/zoDjtiAEkEEZVE6S9fxUmK6FMK3hpwhPClR8g67z/rahxonN JMBg== X-Gm-Message-State: AOJu0Yw70+GqqqqeFVgz16nGA8fKxnvbEkQfTZ3YRAD6CKNHNyaLkCqy DExItae1iWEHCvsPm67Yg50eqTwOGiCZP4MOVnYst5PnhcV78LhmWL0SWNaToGsv7fdh0fKgFbQ Z X-Received: by 2002:adf:f1c2:0:b0:368:3789:1a2 with SMTP id ffacd0b85a97d-37194641ac2mr1951421f8f.21.1723814535469; Fri, 16 Aug 2024 06:22:15 -0700 (PDT) Received: from orth.archaic.org.uk (orth.archaic.org.uk. [2001:8b0:1d0::2]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-371898ab855sm3631948f8f.105.2024.08.16.06.22.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 16 Aug 2024 06:22:15 -0700 (PDT) From: Peter Maydell To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Kevin Wolf , Hanna Reitz , Stefan Hajnoczi Subject: [PATCH 2/7] docs/devel/blkverify: Convert to rST format Date: Fri, 16 Aug 2024 14:22:07 +0100 Message-Id: <20240816132212.3602106-3-peter.maydell@linaro.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240816132212.3602106-1-peter.maydell@linaro.org> References: <20240816132212.3602106-1-peter.maydell@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::42d; envelope-from=peter.maydell@linaro.org; helo=mail-wr1-x42d.google.com 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, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: qemu-devel-bounces+patch=linaro.org@nongnu.org Convert blkverify.txt to rST format. Signed-off-by: Peter Maydell Reviewed-by: Thomas Huth --- MAINTAINERS | 1 + docs/devel/{blkverify.txt => blkverify.rst} | 30 ++++++++++++--------- docs/devel/index-build.rst | 1 + 3 files changed, 19 insertions(+), 13 deletions(-) rename docs/devel/{blkverify.txt => blkverify.rst} (77%) diff --git a/MAINTAINERS b/MAINTAINERS index ca0a5c731f5..e9dd1180077 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3938,6 +3938,7 @@ M: Stefan Hajnoczi L: qemu-block@nongnu.org S: Supported F: block/blkverify.c +F: docs/devel/blkverify.rst bochs M: Stefan Hajnoczi diff --git a/docs/devel/blkverify.txt b/docs/devel/blkverify.rst similarity index 77% rename from docs/devel/blkverify.txt rename to docs/devel/blkverify.rst index aca826c51cc..2a71778b5e3 100644 --- a/docs/devel/blkverify.txt +++ b/docs/devel/blkverify.rst @@ -1,8 +1,10 @@ -= Block driver correctness testing with blkverify = +Block driver correctness testing with ``blkverify`` +=================================================== -== Introduction == +Introduction +------------ -This document describes how to use the blkverify protocol to test that a block +This document describes how to use the ``blkverify`` protocol to test that a block driver is operating correctly. It is difficult to test and debug block drivers against real guests. Often @@ -11,12 +13,13 @@ of the executable. Other times obscure errors are raised by a program inside the guest. These issues are extremely hard to trace back to bugs in the block driver. -Blkverify solves this problem by catching data corruption inside QEMU the first +``blkverify`` solves this problem by catching data corruption inside QEMU the first time bad data is read and reporting the disk sector that is corrupted. -== How it works == +How it works +------------ -The blkverify protocol has two child block devices, the "test" device and the +The ``blkverify`` protocol has two child block devices, the "test" device and the "raw" device. Read/write operations are mirrored to both devices so their state should always be in sync. @@ -25,13 +28,14 @@ contents to the "test" image. The idea is that the "raw" device will handle read/write operations correctly and not corrupt data. It can be used as a reference for comparison against the "test" device. -After a mirrored read operation completes, blkverify will compare the data and +After a mirrored read operation completes, ``blkverify`` will compare the data and raise an error if it is not identical. This makes it possible to catch the first instance where corrupt data is read. -== Example == +Example +------- -Imagine raw.img has 0xcd repeated throughout its first sector: +Imagine raw.img has 0xcd repeated throughout its first sector:: $ ./qemu-io -c 'read -v 0 512' raw.img 00000000: cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd ................ @@ -42,7 +46,7 @@ Imagine raw.img has 0xcd repeated throughout its first sector: read 512/512 bytes at offset 0 512.000000 bytes, 1 ops; 0.0000 sec (97.656 MiB/sec and 200000.0000 ops/sec) -And test.img is corrupt, its first sector is zeroed when it shouldn't be: +And test.img is corrupt, its first sector is zeroed when it shouldn't be:: $ ./qemu-io -c 'read -v 0 512' test.img 00000000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ @@ -53,17 +57,17 @@ And test.img is corrupt, its first sector is zeroed when it shouldn't be: read 512/512 bytes at offset 0 512.000000 bytes, 1 ops; 0.0000 sec (81.380 MiB/sec and 166666.6667 ops/sec) -This error is caught by blkverify: +This error is caught by ``blkverify``:: $ ./qemu-io -c 'read 0 512' blkverify:a.img:b.img blkverify: read sector_num=0 nb_sectors=4 contents mismatch in sector 0 -A more realistic scenario is verifying the installation of a guest OS: +A more realistic scenario is verifying the installation of a guest OS:: $ ./qemu-img create raw.img 16G $ ./qemu-img create -f qcow2 test.qcow2 16G $ ./qemu-system-x86_64 -cdrom debian.iso \ -drive file=blkverify:raw.img:test.qcow2 -If the installation is aborted when blkverify detects corruption, use qemu-io +If the installation is aborted when ``blkverify`` detects corruption, use ``qemu-io`` to explore the contents of the disk image at the sector in question. diff --git a/docs/devel/index-build.rst b/docs/devel/index-build.rst index 3a912aefcfa..a8f7c5cdebc 100644 --- a/docs/devel/index-build.rst +++ b/docs/devel/index-build.rst @@ -19,3 +19,4 @@ the basics if you are adding new files and targets to the build. fuzzing control-flow-integrity blkdebug + blkverify From patchwork Fri Aug 16 13:22:08 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 819737 Delivered-To: patch@linaro.org Received: by 2002:adf:a3c8:0:b0:367:895a:4699 with SMTP id m8csp286680wrb; Fri, 16 Aug 2024 06:23:51 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCVRcAhstVQ43ctpeM0fF1KeCIWEdzfQI7ZtVoElOj49kmR+/jLr5slVugXGM752i+Qlfzsxt0ei42R/YkfMxKkB X-Google-Smtp-Source: AGHT+IGacQXK2KFfv67xVlisFsQ9EzmzLAfgoFAytCyHFajKuBkexwCwdskajRL7HjDH48DY6Smv X-Received: by 2002:a05:6808:150e:b0:3d9:3649:9087 with SMTP id 5614622812f47-3dd3af827f1mr3577679b6e.41.1723814631011; Fri, 16 Aug 2024 06:23:51 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1723814630; cv=none; d=google.com; s=arc-20160816; b=UqHJMq51Q3wzXzEN71zsRWncPOqC3r30ca0ftKj9F7RBNGpbhm4najLkNiUuJmR6VN W9N9p/Uqw+oOLws0QpNYz5W6Ue/DIWiGMfr2m54WDmneoRjTPy8gy/bPcTdVLKP2w5eE UbFaCM7V448I+bHjkSXIvtZ1ilSg+noHyx2GfJsjpjCZnPKy+PqfPCIoF6/cpXDJxTxN ylUHFXVfSFs/ahvLVAz3y2DDdQ53CRR0+rF+W3z8KV5qR9XtPTpyw+hy2eq1Fi8E+YGi ZesFrD91TfGvc3MHgoPE8tphsssfrDd2NyRKUDSstHGhNNZ29Oan/0X0ELXpxaNfMqUv jXfA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=w0Uc190Y4kUeif42FgIZy4DdRtiwAx6zfSHmj9YJomk=; fh=NVInRNxxVvpKCXHA+YUXRIpSUGsR0gcBKdN/9cCMaL0=; b=ODFyBZLaou2NDsI1KxHd2B2+yAfT7S1lkxd//LC3xinp0bTfklFWM3XG8nMB1eQe6M xAuGswqFim0JkUlAyqm55GX2z5lgDcNsuS6GgAOn47R/ITcuIogG62/4veJrdEwOPub7 nCO/qy4fqGnvrEHLoTp1N7QypE94VepauB8DdaEIJN8c7zDVEx5BU9drzOR4GQpsq8En JXVXBOt6n83WTcHnD7hhEIYJUDDMdGaMU2BNjszaqZTibhPZaVi0EFlELmRCSbgf9wC6 KtkiMHngEmUFl9fH9lLQUj8n/C5RPEz82fvCjg2hK0g8djWlh4/JZCjnLmxJsILjmR70 kCNQ==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=uihpPkB0; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org; dara=neutral header.i=@linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id d75a77b69052e-4536a0e7636si39568881cf.702.2024.08.16.06.23.50 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Fri, 16 Aug 2024 06:23:50 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=uihpPkB0; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org; dara=neutral header.i=@linaro.org Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sewuM-0005Cm-9k; Fri, 16 Aug 2024 09:22:25 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sewuK-00058S-Ff for qemu-devel@nongnu.org; Fri, 16 Aug 2024 09:22:20 -0400 Received: from mail-wm1-x32c.google.com ([2a00:1450:4864:20::32c]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1sewuH-0007k7-LS for qemu-devel@nongnu.org; Fri, 16 Aug 2024 09:22:20 -0400 Received: by mail-wm1-x32c.google.com with SMTP id 5b1f17b1804b1-42817bee9e8so13642215e9.3 for ; Fri, 16 Aug 2024 06:22:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1723814536; x=1724419336; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=w0Uc190Y4kUeif42FgIZy4DdRtiwAx6zfSHmj9YJomk=; b=uihpPkB0Xwo8tQ5R0pueH7EIBwakkhBYbhZfn0XHAyksQv1u/GC5qdrP37xOZNAQ1X RgypTqLKIF9oBFcE+Z9yLIkb8TVFHWwRvriyHn6sgv6UUUbs8YwFjkcPTlL1fycou58d rRArOKv3Rx/HsZJETyb9io/WAEor6haTx7ciJJtLvTyprFChm92Xo/KdwurvudHEVuv0 qKvAOK9pLSzlsCOZEVKiS2qEnxjtAsM1DEsE1DDLRWUxroniQsu07vte780DvS8b56WP pvSjL0pf5/TLtrNZA7sEor0QitSn39hPP9DnWFnz7OaBiR4GqaTBp/CI/Mvz66ORaOcr NCrA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1723814536; x=1724419336; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=w0Uc190Y4kUeif42FgIZy4DdRtiwAx6zfSHmj9YJomk=; b=rjANr4cTQUtJeKPbeyhZeOq24hI7U4C/lPFK6BspmRzkiOwxOwpb+GOA0UIWm2NfVU T+QFLyBSIu9DHdoRTZ2YKw0K5MW+88uBAwTP9kX5R6yrGDcWzj+GKbUI5H0rnfrMpfva yd0mOGxNcYTnn2h/F1qUJ7d8VFyvwSBgu5LhnlvdoJ3De4WKwCcoLB+lyyc/WIDp3uPf 2pzFrKSLU9SVlbfLULIVkWRI23w1keBoC4ciNYXfHzfjjUxok49Z7mCuyo0aWU8jkqFS OxJMEAxrCazA1ClBN2eurfEIjwaoSqdNLw39YNQBH99nLNybBpPUpJ+b/HsRCnDfhuGt E39g== X-Gm-Message-State: AOJu0YxsbCpGb+b35RQEpHiolWWEocd4tm2ZgvsQ+yFrKiDjKCC0Hw/e 8FaMsYTRFFIUg5EY9Srn8cHN/5RWuBNWiTsJ2+nOf+aoXhhGzGEfwBwogvBKlsLl+a1vjtjSCPZ W X-Received: by 2002:a5d:694a:0:b0:368:31c7:19d3 with SMTP id ffacd0b85a97d-3719431e723mr1869776f8f.9.1723814536038; Fri, 16 Aug 2024 06:22:16 -0700 (PDT) Received: from orth.archaic.org.uk (orth.archaic.org.uk. [2001:8b0:1d0::2]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-371898ab855sm3631948f8f.105.2024.08.16.06.22.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 16 Aug 2024 06:22:15 -0700 (PDT) From: Peter Maydell To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Kevin Wolf , Hanna Reitz , Stefan Hajnoczi Subject: [PATCH 3/7] docs/devel/lockcnt: Convert to rST format Date: Fri, 16 Aug 2024 14:22:08 +0100 Message-Id: <20240816132212.3602106-4-peter.maydell@linaro.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240816132212.3602106-1-peter.maydell@linaro.org> References: <20240816132212.3602106-1-peter.maydell@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::32c; envelope-from=peter.maydell@linaro.org; helo=mail-wm1-x32c.google.com 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, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: qemu-devel-bounces+patch=linaro.org@nongnu.org Convert docs/devel/lockcnt.txt to rST format. Signed-off-by: Peter Maydell --- MAINTAINERS | 2 +- docs/devel/index-api.rst | 1 + docs/devel/{lockcnt.txt => lockcnt.rst} | 89 +++++++++++++------------ 3 files changed, 47 insertions(+), 45 deletions(-) rename docs/devel/{lockcnt.txt => lockcnt.rst} (74%) diff --git a/MAINTAINERS b/MAINTAINERS index e9dd1180077..9e091a4e214 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3112,7 +3112,7 @@ F: qapi/run-state.json Read, Copy, Update (RCU) M: Paolo Bonzini S: Maintained -F: docs/devel/lockcnt.txt +F: docs/devel/lockcnt.rst F: docs/devel/rcu.txt F: include/qemu/rcu*.h F: tests/unit/rcutorture.c diff --git a/docs/devel/index-api.rst b/docs/devel/index-api.rst index fe01b2b488d..1c487c152ab 100644 --- a/docs/devel/index-api.rst +++ b/docs/devel/index-api.rst @@ -9,6 +9,7 @@ generated from in-code annotations to function prototypes. bitops loads-stores + lockcnt memory modules pci diff --git a/docs/devel/lockcnt.txt b/docs/devel/lockcnt.rst similarity index 74% rename from docs/devel/lockcnt.txt rename to docs/devel/lockcnt.rst index a3fb3bc5d8d..994aeb57151 100644 --- a/docs/devel/lockcnt.txt +++ b/docs/devel/lockcnt.rst @@ -1,9 +1,9 @@ -DOCUMENTATION FOR LOCKED COUNTERS (aka QemuLockCnt) -=================================================== +Locked Counters (aka ``QemuLockCnt``) +===================================== QEMU often uses reference counts to track data structures that are being accessed and should not be freed. For example, a loop that invoke -callbacks like this is not safe: +callbacks like this is not safe:: QLIST_FOREACH_SAFE(ioh, &io_handlers, next, pioh) { if (ioh->revents & G_IO_OUT) { @@ -11,11 +11,11 @@ callbacks like this is not safe: } } -QLIST_FOREACH_SAFE protects against deletion of the current node (ioh) -by stashing away its "next" pointer. However, ioh->fd_write could +``QLIST_FOREACH_SAFE`` protects against deletion of the current node (``ioh``) +by stashing away its ``next`` pointer. However, ``ioh->fd_write`` could actually delete the next node from the list. The simplest way to avoid this is to mark the node as deleted, and remove it from the -list in the above loop: +list in the above loop:: QLIST_FOREACH_SAFE(ioh, &io_handlers, next, pioh) { if (ioh->deleted) { @@ -29,7 +29,7 @@ list in the above loop: } If however this loop must also be reentrant, i.e. it is possible that -ioh->fd_write invokes the loop again, some kind of counting is needed: +``ioh->fd_write`` invokes the loop again, some kind of counting is needed:: walking_handlers++; QLIST_FOREACH_SAFE(ioh, &io_handlers, next, pioh) { @@ -46,8 +46,8 @@ ioh->fd_write invokes the loop again, some kind of counting is needed: } walking_handlers--; -One may think of using the RCU primitives, rcu_read_lock() and -rcu_read_unlock(); effectively, the RCU nesting count would take +One may think of using the RCU primitives, ``rcu_read_lock()`` and +``rcu_read_unlock()``; effectively, the RCU nesting count would take the place of the walking_handlers global variable. Indeed, reference counting and RCU have similar purposes, but their usage in general is complementary: @@ -70,14 +70,14 @@ general is complementary: this can improve performance, but also delay reclamation undesirably. With reference counting, reclamation is deterministic. -This file documents QemuLockCnt, an abstraction for using reference +This file documents ``QemuLockCnt``, an abstraction for using reference counting in code that has to be both thread-safe and reentrant. -QemuLockCnt concepts --------------------- +``QemuLockCnt`` concepts +------------------------ -A QemuLockCnt comprises both a counter and a mutex; it has primitives +A ``QemuLockCnt`` comprises both a counter and a mutex; it has primitives to increment and decrement the counter, and to take and release the mutex. The counter notes how many visits to the data structures are taking place (the visits could be from different threads, or there could @@ -95,13 +95,14 @@ not just frees, though there could be cases where this is not necessary. Reads, instead, can be done without taking the mutex, as long as the readers and writers use the same macros that are used for RCU, for -example qatomic_rcu_read, qatomic_rcu_set, QLIST_FOREACH_RCU, etc. This is -because the reads are done outside a lock and a set or QLIST_INSERT_HEAD +example ``qatomic_rcu_read``, ``qatomic_rcu_set``, ``QLIST_FOREACH_RCU``, +etc. This is because the reads are done outside a lock and a set +or ``QLIST_INSERT_HEAD`` can happen concurrently with the read. The RCU API ensures that the processor and the compiler see all required memory barriers. This could be implemented simply by protecting the counter with the -mutex, for example: +mutex, for example:: // (1) qemu_mutex_lock(&walking_handlers_mutex); @@ -125,33 +126,33 @@ mutex, for example: Here, no frees can happen in the code represented by the ellipsis. If another thread is executing critical section (2), that part of the code cannot be entered, because the thread will not be able -to increment the walking_handlers variable. And of course +to increment the ``walking_handlers`` variable. And of course during the visit any other thread will see a nonzero value for -walking_handlers, as in the single-threaded code. +``walking_handlers``, as in the single-threaded code. Note that it is possible for multiple concurrent accesses to delay -the cleanup arbitrarily; in other words, for the walking_handlers +the cleanup arbitrarily; in other words, for the ``walking_handlers`` counter to never become zero. For this reason, this technique is more easily applicable if concurrent access to the structure is rare. However, critical sections are easy to forget since you have to do -them for each modification of the counter. QemuLockCnt ensures that +them for each modification of the counter. ``QemuLockCnt`` ensures that all modifications of the counter take the lock appropriately, and it can also be more efficient in two ways: - it avoids taking the lock for many operations (for example incrementing the counter while it is non-zero); -- on some platforms, one can implement QemuLockCnt to hold the lock +- on some platforms, one can implement ``QemuLockCnt`` to hold the lock and the mutex in a single word, making the fast path no more expensive than simply managing a counter using atomic operations (see - docs/devel/atomics.rst). This can be very helpful if concurrent access to + :doc:`atomics`). This can be very helpful if concurrent access to the data structure is expected to be rare. Using the same mutex for frees and writes can still incur some small inefficiencies; for example, a visit can never start if the counter is -zero and the mutex is taken---even if the mutex is taken by a write, +zero and the mutex is taken -- even if the mutex is taken by a write, which in principle need not block a visit of the data structure. However, these are usually not a problem if any of the following assumptions are valid: @@ -163,27 +164,27 @@ assumptions are valid: - writes are frequent, but this kind of write (e.g. appending to a list) has a very small critical section. -For example, QEMU uses QemuLockCnt to manage an AioContext's list of +For example, QEMU uses ``QemuLockCnt`` to manage an ``AioContext``'s list of bottom halves and file descriptor handlers. Modifications to the list of file descriptor handlers are rare. Creation of a new bottom half is frequent and can happen on a fast path; however: 1) it is almost never concurrent with a visit to the list of bottom halves; 2) it only has -three instructions in the critical path, two assignments and a smp_wmb(). +three instructions in the critical path, two assignments and a ``smp_wmb()``. -QemuLockCnt API ---------------- +``QemuLockCnt`` API +------------------- -The QemuLockCnt API is described in include/qemu/thread.h. +The ``QemuLockCnt`` API is described in ``include/qemu/thread.h``. -QemuLockCnt usage ------------------ +``QemuLockCnt`` usage +--------------------- -This section explains the typical usage patterns for QemuLockCnt functions. +This section explains the typical usage patterns for ``QemuLockCnt`` functions. Setting a variable to a non-NULL value can be done between -qemu_lockcnt_lock and qemu_lockcnt_unlock: +``qemu_lockcnt_lock`` and ``qemu_lockcnt_unlock``:: qemu_lockcnt_lock(&xyz_lockcnt); if (!xyz) { @@ -193,8 +194,8 @@ qemu_lockcnt_lock and qemu_lockcnt_unlock: } qemu_lockcnt_unlock(&xyz_lockcnt); -Accessing the value can be done between qemu_lockcnt_inc and -qemu_lockcnt_dec: +Accessing the value can be done between ``qemu_lockcnt_inc`` and +``qemu_lockcnt_dec``:: qemu_lockcnt_inc(&xyz_lockcnt); if (xyz) { @@ -204,11 +205,11 @@ qemu_lockcnt_dec: } qemu_lockcnt_dec(&xyz_lockcnt); -Freeing the object can similarly use qemu_lockcnt_lock and -qemu_lockcnt_unlock, but you also need to ensure that the count -is zero (i.e. there is no concurrent visit). Because qemu_lockcnt_inc -takes the QemuLockCnt's lock, the count cannot become non-zero while -the object is being freed. Freeing an object looks like this: +Freeing the object can similarly use ``qemu_lockcnt_lock`` and +``qemu_lockcnt_unlock``, but you also need to ensure that the count +is zero (i.e. there is no concurrent visit). Because ``qemu_lockcnt_inc`` +takes the ``QemuLockCnt``'s lock, the count cannot become non-zero while +the object is being freed. Freeing an object looks like this:: qemu_lockcnt_lock(&xyz_lockcnt); if (!qemu_lockcnt_count(&xyz_lockcnt)) { @@ -218,7 +219,7 @@ the object is being freed. Freeing an object looks like this: qemu_lockcnt_unlock(&xyz_lockcnt); If an object has to be freed right after a visit, you can combine -the decrement, the locking and the check on count as follows: +the decrement, the locking and the check on count as follows:: qemu_lockcnt_inc(&xyz_lockcnt); if (xyz) { @@ -232,7 +233,7 @@ the decrement, the locking and the check on count as follows: qemu_lockcnt_unlock(&xyz_lockcnt); } -QemuLockCnt can also be used to access a list as follows: +``QemuLockCnt`` can also be used to access a list as follows:: qemu_lockcnt_inc(&io_handlers_lockcnt); QLIST_FOREACH_RCU(ioh, &io_handlers, pioh) { @@ -252,10 +253,10 @@ QemuLockCnt can also be used to access a list as follows: } Again, the RCU primitives are used because new items can be added to the -list during the walk. QLIST_FOREACH_RCU ensures that the processor and +list during the walk. ``QLIST_FOREACH_RCU`` ensures that the processor and the compiler see the appropriate memory barriers. -An alternative pattern uses qemu_lockcnt_dec_if_lock: +An alternative pattern uses ``qemu_lockcnt_dec_if_lock``:: qemu_lockcnt_inc(&io_handlers_lockcnt); QLIST_FOREACH_SAFE_RCU(ioh, &io_handlers, next, pioh) { @@ -273,5 +274,5 @@ An alternative pattern uses qemu_lockcnt_dec_if_lock: } qemu_lockcnt_dec(&io_handlers_lockcnt); -Here you can use qemu_lockcnt_dec instead of qemu_lockcnt_dec_and_lock, +Here you can use ``qemu_lockcnt_dec`` instead of ``qemu_lockcnt_dec_and_lock``, because there is no special task to do if the count goes from 1 to 0. From patchwork Fri Aug 16 13:22:09 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 819739 Delivered-To: patch@linaro.org Received: by 2002:adf:a3c8:0:b0:367:895a:4699 with SMTP id m8csp286952wrb; Fri, 16 Aug 2024 06:24:16 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCVDgNYG+xZmsIIMgBVcpyECT7n34LU09bQPBfLT8NYO7M7D4iP5KjTU/OTD0FEgbyDHDx6tMoF1882yw6M2VO8X X-Google-Smtp-Source: AGHT+IFwQHZ1583wa9IBRs2lHb6Ahm9mgQmG00UUq3+ZtFCCfPj2e7ZjJP4NPhxXzTYqJyzdEi+2 X-Received: by 2002:a05:620a:4441:b0:7a1:da5e:c4c8 with SMTP id af79cd13be357-7a506956b3dmr355230885a.40.1723814656223; Fri, 16 Aug 2024 06:24:16 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1723814656; cv=none; d=google.com; s=arc-20160816; b=jyt1A/L88b13Aocw+JMM8g7YOG82Q2dQGRF/5Dlr4SjxayNDza+kJAlnKmpY3j5YuR ClFei7Kv8YLBKGbokJDZVP0lZb3JNyznrXPzYfSe7ND1x4STVcX6/XdY3eIPDU5/iE2m 4EufIXh11oGPOD6HuqDQ8L53epdRkZKvZKPShKzqzsUstWCRMaA03+seHYIG+z3PYAZe RexWuTE3L72+XZDvvFIwLwZIHO8uEUlSgXC0Baus/1ohwQiygMOCH1w1K4D2TFsn6T6x VuWT8oiq2GrVLNkj7axaHba2a5a4uNaHM/KYPwFU8URM9ube5Qs1p6ZJP/RkoaL8oREg pf9g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=ePF/o/hQSoaSIDuJhqV/fjOlqlj+BNS3IyHKpKM6oQg=; fh=NVInRNxxVvpKCXHA+YUXRIpSUGsR0gcBKdN/9cCMaL0=; b=nmxjC7pSPoW7WQCH8cQIdkNlHm8pXn6oOu0DMc/UaQ5dGyKZtXSAqb+oTZIy//+mSf FBUWUg4Z+2qo7vLIA76atHHt0UR+ZFzb967+EDE0xv736qLJque+OKOWRUbXUAsDue8y GYs53hM2KS72TGTTmI0hqNZt3g2A2rPrJCx3ksna1t3KIOcHsz3o2+gXIOu6VC33HOBV seffOz80LcBxEL81gxlRXi7Uqix9233bx0C1ZKngS+VJi2V897+pfqw15mLrqoYN83qK Em41Js2xxK54Ex4DdYOJ3aNEZLmkvofwJxND4c4XxVymM0OBT9l8YwJYpCI/FcUIcxxx DElA==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=mrqVp0OB; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org; dara=neutral header.i=@linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id af79cd13be357-7a4ff112e7csi410808985a.633.2024.08.16.06.24.15 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Fri, 16 Aug 2024 06:24:16 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=mrqVp0OB; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org; dara=neutral header.i=@linaro.org Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sewuQ-0005Sz-WB; Fri, 16 Aug 2024 09:22:27 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sewuM-0005Bi-1Z for qemu-devel@nongnu.org; Fri, 16 Aug 2024 09:22:22 -0400 Received: from mail-wr1-x431.google.com ([2a00:1450:4864:20::431]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1sewuJ-0007kL-Fo for qemu-devel@nongnu.org; Fri, 16 Aug 2024 09:22:21 -0400 Received: by mail-wr1-x431.google.com with SMTP id ffacd0b85a97d-3687ea0521cso1269392f8f.1 for ; Fri, 16 Aug 2024 06:22:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1723814537; x=1724419337; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=ePF/o/hQSoaSIDuJhqV/fjOlqlj+BNS3IyHKpKM6oQg=; b=mrqVp0OBcAe4Hn1oFWMxipmza+iw5QK4XAYyViPj8Zsck1o8LEqSTZij4kGPkX90yj MoEM/y+JrLduP8JKfWyAx6sksz6xYc3+lkxB7/qFfAEMcYOeNmlkBRueoQuW5fwCpmYc BkTR020xNhH2kHO1dO5DEeAht1mAHnDhaRNRAyDmSLV2cXLoMaXjo2VenG844KpEzLZD vgOdn/s3DXNtLnNSnwHHL9E3vkmnmWLHyWCcEIiM4jAbxuapDlRJBp1LkbTstZNpGSzB njm3SHDEEsphQfYGWetUQoTlcRoLVxVNyn2Op946Psj9QKOyHwoiR5PV8XEjXJDa0JKj D1Lw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1723814537; x=1724419337; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ePF/o/hQSoaSIDuJhqV/fjOlqlj+BNS3IyHKpKM6oQg=; b=XpYpxeMauC0YCoH1v0SoxxAYEKYb1wRe2e+6bUUkvj3ayvMsDGC8Bh6fb/POeykUZI sIf9ySNJQgHE+yZHaLuxbe/klfhhIRcCAd3f8HzOZiSdpLkRsbK7cuOAaQK46aENkvDV cmr0Gpj4Qf/kUZsHXmH6UxaotpobVX+jGlTGGP2LEpLrpPK2qZ4DF/V5rIT/pF43y9q6 QATxmVaoCDV6uj4C2fx6d3uKSh/sFdIz+xxT5Sn2ViIY8uca410G+Gs0AbxKPtU838Ha 0lzbdtiX4AMSvRkk2+1M5pzZDYXD+SDtdexkt6yfJGrg8CCLPBufIoZmTeZS2xnyuGKL ioRA== X-Gm-Message-State: AOJu0Yyur1tk8Fd/ra8HYQG8eYcTkFx0coAtdCK9/cdcwxy91gksQE60 F5ikkl5z3kkNOLYQLW8kPeVHob0Q50IV+JIxYsbayr5cOmxmgkYsCE/sLHuJofORs/lLKH2T1xx N X-Received: by 2002:a5d:4e42:0:b0:371:8eea:24b7 with SMTP id ffacd0b85a97d-371946a04e6mr2246256f8f.50.1723814537151; Fri, 16 Aug 2024 06:22:17 -0700 (PDT) Received: from orth.archaic.org.uk (orth.archaic.org.uk. [2001:8b0:1d0::2]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-371898ab855sm3631948f8f.105.2024.08.16.06.22.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 16 Aug 2024 06:22:16 -0700 (PDT) From: Peter Maydell To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Kevin Wolf , Hanna Reitz , Stefan Hajnoczi Subject: [PATCH 4/7] docs/devel/multiple-iothreads: Convert to rST format Date: Fri, 16 Aug 2024 14:22:09 +0100 Message-Id: <20240816132212.3602106-5-peter.maydell@linaro.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240816132212.3602106-1-peter.maydell@linaro.org> References: <20240816132212.3602106-1-peter.maydell@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::431; envelope-from=peter.maydell@linaro.org; helo=mail-wr1-x431.google.com 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, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: qemu-devel-bounces+patch=linaro.org@nongnu.org Convert docs/devel/multiple-iothreads.txt to rST format. Signed-off-by: Peter Maydell --- docs/devel/index-internals.rst | 1 + docs/devel/multiple-iothreads.rst | 139 ++++++++++++++++++++++++++++++ docs/devel/multiple-iothreads.txt | 130 ---------------------------- 3 files changed, 140 insertions(+), 130 deletions(-) create mode 100644 docs/devel/multiple-iothreads.rst delete mode 100644 docs/devel/multiple-iothreads.txt diff --git a/docs/devel/index-internals.rst b/docs/devel/index-internals.rst index 4ac7725d728..88fa0e9450d 100644 --- a/docs/devel/index-internals.rst +++ b/docs/devel/index-internals.rst @@ -21,3 +21,4 @@ Details about QEMU's various subsystems including how to add features to them. writing-monitor-commands virtio-backends crypto + multiple-iothreads diff --git a/docs/devel/multiple-iothreads.rst b/docs/devel/multiple-iothreads.rst new file mode 100644 index 00000000000..d1f3fc4510a --- /dev/null +++ b/docs/devel/multiple-iothreads.rst @@ -0,0 +1,139 @@ +Using Multiple ``IOThread``\ s +============================== + +.. + Copyright (c) 2014-2017 Red Hat Inc. + + This work is licensed under the terms of the GNU GPL, version 2 or later. See + the COPYING file in the top-level directory. + + +This document explains the ``IOThread`` feature and how to write code that runs +outside the BQL. + +The main loop and ``IOThread``\ s +--------------------------------- +QEMU is an event-driven program that can do several things at once using an +event loop. The VNC server and the QMP monitor are both processed from the +same event loop, which monitors their file descriptors until they become +readable and then invokes a callback. + +The default event loop is called the main loop (see ``main-loop.c``). It is +possible to create additional event loop threads using +``-object iothread,id=my-iothread``. + +Side note: The main loop and ``IOThread`` are both event loops but their code is +not shared completely. Sometimes it is useful to remember that although they +are conceptually similar they are currently not interchangeable. + +Why ``IOThread``\ s are useful +------------------------------ +``IOThread``\ s allow the user to control the placement of work. The main loop is a +scalability bottleneck on hosts with many CPUs. Work can be spread across +several ``IOThread``\ s instead of just one main loop. When set up correctly this +can improve I/O latency and reduce jitter seen by the guest. + +The main loop is also deeply associated with the BQL, which is a +scalability bottleneck in itself. vCPU threads and the main loop use the BQL +to serialize execution of QEMU code. This mutex is necessary because a lot of +QEMU's code historically was not thread-safe. + +The fact that all I/O processing is done in a single main loop and that the +BQL is contended by all vCPU threads and the main loop explain +why it is desirable to place work into ``IOThread``\ s. + +The experimental ``virtio-blk`` data-plane implementation has been benchmarked and +shows these effects: +ftp://public.dhe.ibm.com/linux/pdfs/KVM_Virtualized_IO_Performance_Paper.pdf + +.. _how-to-program: + +How to program for ``IOThread``\ s +---------------------------------- +The main difference between legacy code and new code that can run in an +``IOThread`` is dealing explicitly with the event loop object, ``AioContext`` +(see ``include/block/aio.h``). Code that only works in the main loop +implicitly uses the main loop's ``AioContext``. Code that supports running +in ``IOThread``\ s must be aware of its ``AioContext``. + +AioContext supports the following services: + * File descriptor monitoring (read/write/error on POSIX hosts) + * Event notifiers (inter-thread signalling) + * Timers + * Bottom Halves (BH) deferred callbacks + +There are several old APIs that use the main loop AioContext: + * LEGACY ``qemu_aio_set_fd_handler()`` - monitor a file descriptor + * LEGACY ``qemu_aio_set_event_notifier()`` - monitor an event notifier + * LEGACY ``timer_new_ms()`` - create a timer + * LEGACY ``qemu_bh_new()`` - create a BH + * LEGACY ``qemu_bh_new_guarded()`` - create a BH with a device re-entrancy guard + * LEGACY ``qemu_aio_wait()`` - run an event loop iteration + +Since they implicitly work on the main loop they cannot be used in code that +runs in an ``IOThread``. They might cause a crash or deadlock if called from an +``IOThread`` since the BQL is not held. + +Instead, use the ``AioContext`` functions directly (see ``include/block/aio.h``): + * ``aio_set_fd_handler()`` - monitor a file descriptor + * ``aio_set_event_notifier()`` - monitor an event notifier + * ``aio_timer_new()`` - create a timer + * ``aio_bh_new()`` - create a BH + * ``aio_bh_new_guarded()`` - create a BH with a device re-entrancy guard + * ``aio_poll()`` - run an event loop iteration + +The ``qemu_bh_new_guarded``/``aio_bh_new_guarded`` APIs accept a +``MemReentrancyGuard`` +argument, which is used to check for and prevent re-entrancy problems. For +BHs associated with devices, the reentrancy-guard is contained in the +corresponding ``DeviceState`` and named ``mem_reentrancy_guard``. + +The ``AioContext`` can be obtained from the ``IOThread`` using +``iothread_get_aio_context()`` or for the main loop using +``qemu_get_aio_context()``. Code that takes an ``AioContext`` argument +works both in ``IOThread``\ s or the main loop, depending on which ``AioContext`` +instance the caller passes in. + +How to synchronize with an ``IOThread`` +--------------------------------------- +Variables that can be accessed by multiple threads require some form of +synchronization such as ``qemu_mutex_lock()``, ``rcu_read_lock()``, etc. + +``AioContext`` functions like ``aio_set_fd_handler()``, +``aio_set_event_notifier()``, ``aio_bh_new()``, and ``aio_timer_new()`` +are thread-safe. They can be used to trigger activity in an ``IOThread``. + +Side note: the best way to schedule a function call across threads is to call +``aio_bh_schedule_oneshot()``. + +The main loop thread can wait synchronously for a condition using +``AIO_WAIT_WHILE()``. + +``AioContext`` and the block layer +---------------------------------- +The ``AioContext`` originates from the QEMU block layer, even though nowadays +``AioContext`` is a generic event loop that can be used by any QEMU subsystem. + +The block layer has support for ``AioContext`` integrated. Each +``BlockDriverState`` is associated with an ``AioContext`` using +``bdrv_try_change_aio_context()`` and ``bdrv_get_aio_context()``. +This allows block layer code to process I/O inside the +right ``AioContext``. Other subsystems may wish to follow a similar approach. + +Block layer code must therefore expect to run in an ``IOThread`` and avoid using +old APIs that implicitly use the main loop. See +`How to program for IOThreads`_ for information on how to do that. + +Code running in the monitor typically needs to ensure that past +requests from the guest are completed. When a block device is running +in an ``IOThread``, the ``IOThread`` can also process requests from the guest +(via ioeventfd). To achieve both objects, wrap the code between +``bdrv_drained_begin()`` and ``bdrv_drained_end()``, thus creating a "drained +section". + +Long-running jobs (usually in the form of coroutines) are often scheduled in +the ``BlockDriverState``'s ``AioContext``. The functions +``bdrv_add``/``remove_aio_context_notifier``, or alternatively +``blk_add``/``remove_aio_context_notifier`` if you use ``BlockBackends``, +can be used to get a notification whenever ``bdrv_try_change_aio_context()`` +moves a ``BlockDriverState`` to a different ``AioContext``. diff --git a/docs/devel/multiple-iothreads.txt b/docs/devel/multiple-iothreads.txt deleted file mode 100644 index de85767b124..00000000000 --- a/docs/devel/multiple-iothreads.txt +++ /dev/null @@ -1,130 +0,0 @@ -Copyright (c) 2014-2017 Red Hat Inc. - -This work is licensed under the terms of the GNU GPL, version 2 or later. See -the COPYING file in the top-level directory. - - -This document explains the IOThread feature and how to write code that runs -outside the BQL. - -The main loop and IOThreads ---------------------------- -QEMU is an event-driven program that can do several things at once using an -event loop. The VNC server and the QMP monitor are both processed from the -same event loop, which monitors their file descriptors until they become -readable and then invokes a callback. - -The default event loop is called the main loop (see main-loop.c). It is -possible to create additional event loop threads using -object -iothread,id=my-iothread. - -Side note: The main loop and IOThread are both event loops but their code is -not shared completely. Sometimes it is useful to remember that although they -are conceptually similar they are currently not interchangeable. - -Why IOThreads are useful ------------------------- -IOThreads allow the user to control the placement of work. The main loop is a -scalability bottleneck on hosts with many CPUs. Work can be spread across -several IOThreads instead of just one main loop. When set up correctly this -can improve I/O latency and reduce jitter seen by the guest. - -The main loop is also deeply associated with the BQL, which is a -scalability bottleneck in itself. vCPU threads and the main loop use the BQL -to serialize execution of QEMU code. This mutex is necessary because a lot of -QEMU's code historically was not thread-safe. - -The fact that all I/O processing is done in a single main loop and that the -BQL is contended by all vCPU threads and the main loop explain -why it is desirable to place work into IOThreads. - -The experimental virtio-blk data-plane implementation has been benchmarked and -shows these effects: -ftp://public.dhe.ibm.com/linux/pdfs/KVM_Virtualized_IO_Performance_Paper.pdf - -How to program for IOThreads ----------------------------- -The main difference between legacy code and new code that can run in an -IOThread is dealing explicitly with the event loop object, AioContext -(see include/block/aio.h). Code that only works in the main loop -implicitly uses the main loop's AioContext. Code that supports running -in IOThreads must be aware of its AioContext. - -AioContext supports the following services: - * File descriptor monitoring (read/write/error on POSIX hosts) - * Event notifiers (inter-thread signalling) - * Timers - * Bottom Halves (BH) deferred callbacks - -There are several old APIs that use the main loop AioContext: - * LEGACY qemu_aio_set_fd_handler() - monitor a file descriptor - * LEGACY qemu_aio_set_event_notifier() - monitor an event notifier - * LEGACY timer_new_ms() - create a timer - * LEGACY qemu_bh_new() - create a BH - * LEGACY qemu_bh_new_guarded() - create a BH with a device re-entrancy guard - * LEGACY qemu_aio_wait() - run an event loop iteration - -Since they implicitly work on the main loop they cannot be used in code that -runs in an IOThread. They might cause a crash or deadlock if called from an -IOThread since the BQL is not held. - -Instead, use the AioContext functions directly (see include/block/aio.h): - * aio_set_fd_handler() - monitor a file descriptor - * aio_set_event_notifier() - monitor an event notifier - * aio_timer_new() - create a timer - * aio_bh_new() - create a BH - * aio_bh_new_guarded() - create a BH with a device re-entrancy guard - * aio_poll() - run an event loop iteration - -The qemu_bh_new_guarded/aio_bh_new_guarded APIs accept a "MemReentrancyGuard" -argument, which is used to check for and prevent re-entrancy problems. For -BHs associated with devices, the reentrancy-guard is contained in the -corresponding DeviceState and named "mem_reentrancy_guard". - -The AioContext can be obtained from the IOThread using -iothread_get_aio_context() or for the main loop using qemu_get_aio_context(). -Code that takes an AioContext argument works both in IOThreads or the main -loop, depending on which AioContext instance the caller passes in. - -How to synchronize with an IOThread ------------------------------------ -Variables that can be accessed by multiple threads require some form of -synchronization such as qemu_mutex_lock(), rcu_read_lock(), etc. - -AioContext functions like aio_set_fd_handler(), aio_set_event_notifier(), -aio_bh_new(), and aio_timer_new() are thread-safe. They can be used to trigger -activity in an IOThread. - -Side note: the best way to schedule a function call across threads is to call -aio_bh_schedule_oneshot(). - -The main loop thread can wait synchronously for a condition using -AIO_WAIT_WHILE(). - -AioContext and the block layer ------------------------------- -The AioContext originates from the QEMU block layer, even though nowadays -AioContext is a generic event loop that can be used by any QEMU subsystem. - -The block layer has support for AioContext integrated. Each BlockDriverState -is associated with an AioContext using bdrv_try_change_aio_context() and -bdrv_get_aio_context(). This allows block layer code to process I/O inside the -right AioContext. Other subsystems may wish to follow a similar approach. - -Block layer code must therefore expect to run in an IOThread and avoid using -old APIs that implicitly use the main loop. See the "How to program for -IOThreads" above for information on how to do that. - -Code running in the monitor typically needs to ensure that past -requests from the guest are completed. When a block device is running -in an IOThread, the IOThread can also process requests from the guest -(via ioeventfd). To achieve both objects, wrap the code between -bdrv_drained_begin() and bdrv_drained_end(), thus creating a "drained -section". - -Long-running jobs (usually in the form of coroutines) are often scheduled in -the BlockDriverState's AioContext. The functions -bdrv_add/remove_aio_context_notifier, or alternatively -blk_add/remove_aio_context_notifier if you use BlockBackends, can be used to -get a notification whenever bdrv_try_change_aio_context() moves a -BlockDriverState to a different AioContext. From patchwork Fri Aug 16 13:22:10 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 819736 Delivered-To: patch@linaro.org Received: by 2002:adf:a3c8:0:b0:367:895a:4699 with SMTP id m8csp286410wrb; Fri, 16 Aug 2024 06:23:26 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCU/5B3Nb28LQ/MAVxkR1sGwJQqIJa2o1ajgMJKPLkdBWGjEX0RmA+Ee7EaPRLLKlMdyA0yv5qSpv+bONziGeVOn X-Google-Smtp-Source: AGHT+IEGTJLuGoz8qhTr6ILG0MSER86JTx3t3M17+rMLKojOsvqVZeBCcvgGLYpH6wlVwJaQuGGi X-Received: by 2002:a05:6214:4384:b0:6b7:b236:6964 with SMTP id 6a1803df08f44-6bf7cd79055mr27558666d6.12.1723814605974; Fri, 16 Aug 2024 06:23:25 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1723814605; cv=none; d=google.com; s=arc-20160816; b=JWphEqVjghU46L/DY7z59762cCcpR6A4JUSOVMwBOygX/zaXJaPEMy0n1eFn20yz9J OKXkiA3VaPBDYsWmppKp+shPURXRdipQQ1nLfPbS1ToPcSCvJ3v2nOBZ3M9TptxmHUJl JACkLhtf95WzJn34z7xrDRK+xF8EWhDHdec5S3fse1I0Xlbds3oEPaGqgwJPj5+eu2WG izU2XqVIEPPE1l+6tHRQPNpP6Bqc3uW7xvj6tqYDrF7aZYEp8FaIwaKUoM/rjX5Ho4Ji 6l2eWwUh89GdJ4VFH/kM0nm5XP3S6wq4TwN8vKngeU14oaPH1sq88qriWyL061Yfxzj7 77MA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=uQ6lW85Zu+/OmlzIIJ9luNAHJSF12nY6HV6G44fIzvs=; fh=NVInRNxxVvpKCXHA+YUXRIpSUGsR0gcBKdN/9cCMaL0=; b=bi+XgKQMTuzYsSn0Bs/rnK3Wo69COySNCBiBDzvhdwNkoCQBppHaWby7ozG79mn+sm Z7R4bgoWiUbbIwypBHfW9taWiP6bK5PkSB/iApaIl4bXCsO1O/B3ElClrg/dJ2v9m2ql NOYAa2Xbr+46oBmfP8oGjGjcxOWpKcvpRpycmJnjx/LHEZDbrdUmY7NuRqmK8DRuJUQX k0IMytXiofGsyD8xp12xvGsirj9YftWB3el2YnFMqg2CD+TK/L+NI5gH5CjzyDLIeeJP BzFq9kEFfOO/uQDIKizuJy4amvOWYJnm59qMuNhWtj1KiCHvTpNEoGD+9MgYpycFe5SJ H0WA==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=DxifNPKu; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org; dara=neutral header.i=@linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id 6a1803df08f44-6bf6ff0700bsi41026916d6.421.2024.08.16.06.23.25 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Fri, 16 Aug 2024 06:23:25 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=DxifNPKu; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org; dara=neutral header.i=@linaro.org Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sewuV-0005i6-By; Fri, 16 Aug 2024 09:22:31 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sewuM-0005Dz-Hb for qemu-devel@nongnu.org; Fri, 16 Aug 2024 09:22:25 -0400 Received: from mail-wm1-x32a.google.com ([2a00:1450:4864:20::32a]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1sewuJ-0007kW-JD for qemu-devel@nongnu.org; Fri, 16 Aug 2024 09:22:22 -0400 Received: by mail-wm1-x32a.google.com with SMTP id 5b1f17b1804b1-429c4a4c6a8so14655295e9.0 for ; Fri, 16 Aug 2024 06:22:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1723814538; x=1724419338; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=uQ6lW85Zu+/OmlzIIJ9luNAHJSF12nY6HV6G44fIzvs=; b=DxifNPKuFxddrbkTOUSySSxiWM7MUaiuZYHDyl4W6IXf9nJSx5aamA7hcwNBMQE1UH 6pOXTYMphlAwDriEuHf3Z/M/6o+JPEcGo8X6EztzZ2oQkmSUos7yxLnW2/4qPh26d2Qf dp9dGI3ZQyd4KWJ6U+ROjDpm1EGi7JyjQT/EDnPK3flOSI29dQU7nhFc6JEtT5CZECuK TPCzLFi8GE/sSzg1WNZN24eGSADgGUkwF1wwJRbfcW6OxkHDaXDQo9KF4oFUYAp9Tn3v uPvMKPWGJpDRcIrWQZLLbEtrdR8wcF6BD9OZIX1dEnP68E2hDDGSjLOCNwAR9hMOfV06 gejw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1723814538; x=1724419338; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=uQ6lW85Zu+/OmlzIIJ9luNAHJSF12nY6HV6G44fIzvs=; b=J4qHTxqqY12ZHkSuPiKpMLkmzDSZIS8BFrwNo2+4f8G7I+83yH9kK1ouXGnnT9UNR3 3kChlfobhWIaMP6HEEez8ou7xAzQvfhvOjQixCtFABqxAdD+DuoP/Le5O0hza4WpP7+n 7iuHAkhexKtYTzGqF4xTzGWJKcf3yXwxD8orJmS+fl+lNJ9pxdu0RxKwJTAi7xrU2NiK SPGNP0dlXKL3AFw0GnqxVpeQrwsIAbEKoVFyPcOMLnPotWArTfB3FUW3aU3a/ZfHBLrL rnRxj1aXbML86Yc+5t3qq+yZy0PoxZqXg6olmxMuuWV6tnqFp3bI4F9N1mM1QBQAJTQf o4cw== X-Gm-Message-State: AOJu0YyzyhNlt+J5zbAJR1y7+mbqO8ee6b6ISBnpLo21qzDMCpBDFC3O IEiXj64ErNUMeBiMoLCIxFu1MaUmfseNmBzHAQZEPliVPeggDWzxtXAReuWLLT8CnofpCOt6xyQ x X-Received: by 2002:a05:6000:1112:b0:368:714e:5a5e with SMTP id ffacd0b85a97d-3719431764cmr2209985f8f.2.1723814537863; Fri, 16 Aug 2024 06:22:17 -0700 (PDT) Received: from orth.archaic.org.uk (orth.archaic.org.uk. [2001:8b0:1d0::2]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-371898ab855sm3631948f8f.105.2024.08.16.06.22.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 16 Aug 2024 06:22:17 -0700 (PDT) From: Peter Maydell To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Kevin Wolf , Hanna Reitz , Stefan Hajnoczi Subject: [PATCH 5/7] docs/devel/rcu: Convert to rST format Date: Fri, 16 Aug 2024 14:22:10 +0100 Message-Id: <20240816132212.3602106-6-peter.maydell@linaro.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240816132212.3602106-1-peter.maydell@linaro.org> References: <20240816132212.3602106-1-peter.maydell@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::32a; envelope-from=peter.maydell@linaro.org; helo=mail-wm1-x32a.google.com 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, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: qemu-devel-bounces+patch=linaro.org@nongnu.org Convert docs/devel/rcu.txt to rST format. Signed-off-by: Peter Maydell --- MAINTAINERS | 2 +- docs/devel/index-internals.rst | 1 + docs/devel/{rcu.txt => rcu.rst} | 172 +++++++++++++++----------------- 3 files changed, 82 insertions(+), 93 deletions(-) rename docs/devel/{rcu.txt => rcu.rst} (73%) diff --git a/MAINTAINERS b/MAINTAINERS index 9e091a4e214..f8f4df44460 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3113,7 +3113,7 @@ Read, Copy, Update (RCU) M: Paolo Bonzini S: Maintained F: docs/devel/lockcnt.rst -F: docs/devel/rcu.txt +F: docs/devel/rcu.rst F: include/qemu/rcu*.h F: tests/unit/rcutorture.c F: tests/unit/test-rcu-*.c diff --git a/docs/devel/index-internals.rst b/docs/devel/index-internals.rst index 88fa0e9450d..ab9fbc44826 100644 --- a/docs/devel/index-internals.rst +++ b/docs/devel/index-internals.rst @@ -8,6 +8,7 @@ Details about QEMU's various subsystems including how to add features to them. qom atomics + rcu block-coroutine-wrapper clocks ebpf_rss diff --git a/docs/devel/rcu.txt b/docs/devel/rcu.rst similarity index 73% rename from docs/devel/rcu.txt rename to docs/devel/rcu.rst index 2e6cc607a17..dd07c1d9195 100644 --- a/docs/devel/rcu.txt +++ b/docs/devel/rcu.rst @@ -20,7 +20,7 @@ for the execution of all *currently running* critical sections before proceeding, or before asynchronously executing a callback. The key point here is that only the currently running critical sections -are waited for; critical sections that are started _after_ the beginning +are waited for; critical sections that are started **after** the beginning of the wait do not extend the wait, despite running concurrently with the updater. This is the reason why RCU is more scalable than, for example, reader-writer locks. It is so much more scalable that @@ -37,7 +37,7 @@ do not matter; as soon as all previous critical sections have finished, there cannot be any readers who hold references to the data structure, and these can now be safely reclaimed (e.g., freed or unref'ed). -Here is a picture: +Here is a picture:: thread 1 thread 2 thread 3 ------------------- ------------------------ ------------------- @@ -58,43 +58,38 @@ that critical section. RCU API -======= +------- The core RCU API is small: - void rcu_read_lock(void); - +``void rcu_read_lock(void);`` Used by a reader to inform the reclaimer that the reader is entering an RCU read-side critical section. - void rcu_read_unlock(void); - +``void rcu_read_unlock(void);`` Used by a reader to inform the reclaimer that the reader is exiting an RCU read-side critical section. Note that RCU read-side critical sections may be nested and/or overlapping. - void synchronize_rcu(void); - +``void synchronize_rcu(void);`` Blocks until all pre-existing RCU read-side critical sections on all threads have completed. This marks the end of the removal phase and the beginning of reclamation phase. Note that it would be valid for another update to come while - synchronize_rcu is running. Because of this, it is better that + ``synchronize_rcu`` is running. Because of this, it is better that the updater releases any locks it may hold before calling - synchronize_rcu. If this is not possible (for example, because - the updater is protected by the BQL), you can use call_rcu. + ``synchronize_rcu``. If this is not possible (for example, because + the updater is protected by the BQL), you can use ``call_rcu``. - void call_rcu1(struct rcu_head * head, - void (*func)(struct rcu_head *head)); - - This function invokes func(head) after all pre-existing RCU +``void call_rcu1(struct rcu_head * head, void (*func)(struct rcu_head *head));`` + This function invokes ``func(head)`` after all pre-existing RCU read-side critical sections on all threads have completed. This marks the end of the removal phase, with func taking care asynchronously of the reclamation phase. - The foo struct needs to have an rcu_head structure added, - perhaps as follows: + The ``foo`` struct needs to have an ``rcu_head`` structure added, + perhaps as follows:: struct foo { struct rcu_head rcu; @@ -103,8 +98,8 @@ The core RCU API is small: long c; }; - so that the reclaimer function can fetch the struct foo address - and free it: + so that the reclaimer function can fetch the ``struct foo`` address + and free it:: call_rcu1(&foo.rcu, foo_reclaim); @@ -114,29 +109,27 @@ The core RCU API is small: g_free(fp); } - For the common case where the rcu_head member is the first of the - struct, you can use the following macro. + ``call_rcu1`` is typically used via either the ``call_rcu`` or + ``g_free_rcu`` macros, which handle the common case where the + ``rcu_head`` member is the first of the struct. - void call_rcu(T *p, - void (*func)(T *p), - field-name); - void g_free_rcu(T *p, - field-name); +``void call_rcu(T *p, void (*func)(T *p), field-name);`` + If the ``struct rcu_head`` is the first field in the struct, you can + use this macro instead of ``call_rcu1``. - call_rcu1 is typically used through these macro, in the common case - where the "struct rcu_head" is the first field in the struct. If - the callback function is g_free, in particular, g_free_rcu can be - used. In the above case, one could have written simply: +``void g_free_rcu(T *p, field-name);`` + This is a special-case version of ``call_rcu`` where the callback + function is ``g_free``. + In the example given in ``call_rcu1``, one could have written simply:: g_free_rcu(&foo, rcu); - typeof(*p) qatomic_rcu_read(p); +``typeof(*p) qatomic_rcu_read(p);`` + ``qatomic_rcu_read()`` is similar to ``qatomic_load_acquire()``, but + it makes some assumptions on the code that calls it. This allows a + more optimized implementation. - qatomic_rcu_read() is similar to qatomic_load_acquire(), but it makes - some assumptions on the code that calls it. This allows a more - optimized implementation. - - qatomic_rcu_read assumes that whenever a single RCU critical + ``qatomic_rcu_read`` assumes that whenever a single RCU critical section reads multiple shared data, these reads are either data-dependent or need no ordering. This is almost always the case when using RCU, because read-side critical sections typically @@ -144,7 +137,7 @@ The core RCU API is small: every update) until reaching a data structure of interest, and then read from there. - RCU read-side critical sections must use qatomic_rcu_read() to + RCU read-side critical sections must use ``qatomic_rcu_read()`` to read data, unless concurrent writes are prevented by another synchronization mechanism. @@ -152,18 +145,17 @@ The core RCU API is small: data structure in a single direction, opposite to the direction in which the updater initializes it. - void qatomic_rcu_set(p, typeof(*p) v); +``void qatomic_rcu_set(p, typeof(*p) v);`` + ``qatomic_rcu_set()`` is similar to ``qatomic_store_release()``, + though it also makes assumptions on the code that calls it in + order to allow a more optimized implementation. - qatomic_rcu_set() is similar to qatomic_store_release(), though it also - makes assumptions on the code that calls it in order to allow a more - optimized implementation. - - In particular, qatomic_rcu_set() suffices for synchronization + In particular, ``qatomic_rcu_set()`` suffices for synchronization with readers, if the updater never mutates a field within a data item that is already accessible to readers. This is the case when initializing a new copy of the RCU-protected data - structure; just ensure that initialization of *p is carried out - before qatomic_rcu_set() makes the data item visible to readers. + structure; just ensure that initialization of ``*p`` is carried out + before ``qatomic_rcu_set()`` makes the data item visible to readers. If this rule is observed, writes will happen in the opposite order as reads in the RCU read-side critical sections (or if there is just one update), and there will be no need for other @@ -171,58 +163,54 @@ The core RCU API is small: The following APIs must be used before RCU is used in a thread: - void rcu_register_thread(void); - +``void rcu_register_thread(void);`` Mark a thread as taking part in the RCU mechanism. Such a thread will have to report quiescent points regularly, either manually - or through the QemuCond/QemuSemaphore/QemuEvent APIs. - - void rcu_unregister_thread(void); + or through the ``QemuCond``/``QemuSemaphore``/``QemuEvent`` APIs. +``void rcu_unregister_thread(void);`` Mark a thread as not taking part anymore in the RCU mechanism. It is not a problem if such a thread reports quiescent points, - either manually or by using the QemuCond/QemuSemaphore/QemuEvent - APIs. + either manually or by using the + ``QemuCond``/``QemuSemaphore``/``QemuEvent`` APIs. -Note that these APIs are relatively heavyweight, and should _not_ be +Note that these APIs are relatively heavyweight, and should **not** be nested. Convenience macros -================== +------------------ Two macros are provided that automatically release the read lock at the end of the scope. - RCU_READ_LOCK_GUARD() - +``RCU_READ_LOCK_GUARD()`` Takes the lock and will release it at the end of the block it's used in. - WITH_RCU_READ_LOCK_GUARD() { code } - +``WITH_RCU_READ_LOCK_GUARD() { code }`` Is used at the head of a block to protect the code within the block. -Note that 'goto'ing out of the guarded block will also drop the lock. +Note that a ``goto`` out of the guarded block will also drop the lock. -DIFFERENCES WITH LINUX -====================== +Differences with Linux +---------------------- - Waiting on a mutex is possible, though discouraged, within an RCU critical section. This is because spinlocks are rarely (if ever) used in userspace programming; not allowing this would prevent upgrading an RCU read-side critical section to become an updater. -- qatomic_rcu_read and qatomic_rcu_set replace rcu_dereference and - rcu_assign_pointer. They take a _pointer_ to the variable being accessed. +- ``qatomic_rcu_read`` and ``qatomic_rcu_set`` replace ``rcu_dereference`` and + ``rcu_assign_pointer``. They take a **pointer** to the variable being accessed. -- call_rcu is a macro that has an extra argument (the name of the first - field in the struct, which must be a struct rcu_head), and expects the +- ``call_rcu`` is a macro that has an extra argument (the name of the first + field in the struct, which must be a struct ``rcu_head``), and expects the type of the callback's argument to be the type of the first argument. - call_rcu1 is the same as Linux's call_rcu. + ``call_rcu1`` is the same as Linux's ``call_rcu``. -RCU PATTERNS -============ +RCU Patterns +------------ Many patterns using read-writer locks translate directly to RCU, with the advantages of higher scalability and deadlock immunity. @@ -243,28 +231,28 @@ Here are some frequently-used RCU idioms that are worth noting. RCU list processing -------------------- +^^^^^^^^^^^^^^^^^^^ TBD (not yet used in QEMU) RCU reference counting ----------------------- +^^^^^^^^^^^^^^^^^^^^^^ Because grace periods are not allowed to complete while there is an RCU read-side critical section in progress, the RCU read-side primitives may be used as a restricted reference-counting mechanism. For example, -consider the following code fragment: +consider the following code fragment:: rcu_read_lock(); p = qatomic_rcu_read(&foo); /* do something with p. */ rcu_read_unlock(); -The RCU read-side critical section ensures that the value of "p" remains -valid until after the rcu_read_unlock(). In some sense, it is acquiring -a reference to p that is later released when the critical section ends. -The write side looks simply like this (with appropriate locking): +The RCU read-side critical section ensures that the value of ``p`` remains +valid until after the ``rcu_read_unlock()``. In some sense, it is acquiring +a reference to ``p`` that is later released when the critical section ends. +The write side looks simply like this (with appropriate locking):: qemu_mutex_lock(&foo_mutex); old = foo; @@ -274,7 +262,7 @@ The write side looks simply like this (with appropriate locking): free(old); If the processing cannot be done purely within the critical section, it -is possible to combine this idiom with a "real" reference count: +is possible to combine this idiom with a "real" reference count:: rcu_read_lock(); p = qatomic_rcu_read(&foo); @@ -283,7 +271,7 @@ is possible to combine this idiom with a "real" reference count: /* do something with p. */ foo_unref(p); -The write side can be like this: +The write side can be like this:: qemu_mutex_lock(&foo_mutex); old = foo; @@ -292,7 +280,7 @@ The write side can be like this: synchronize_rcu(); foo_unref(old); -or with call_rcu: +or with ``call_rcu``:: qemu_mutex_lock(&foo_mutex); old = foo; @@ -301,10 +289,10 @@ or with call_rcu: call_rcu(foo_unref, old, rcu); In both cases, the write side only performs removal. Reclamation -happens when the last reference to a "foo" object is dropped. -Using synchronize_rcu() is undesirably expensive, because the +happens when the last reference to a ``foo`` object is dropped. +Using ``synchronize_rcu()`` is undesirably expensive, because the last reference may be dropped on the read side. Hence you can -use call_rcu() instead: +use ``call_rcu()`` instead:: foo_unref(struct foo *p) { if (qatomic_fetch_dec(&p->refcount) == 1) { @@ -314,7 +302,7 @@ use call_rcu() instead: Note that the same idioms would be possible with reader/writer -locks: +locks:: read_lock(&foo_rwlock); write_mutex_lock(&foo_rwlock); p = foo; p = foo; @@ -334,15 +322,15 @@ locks: foo_unref(p); read_unlock(&foo_rwlock); -foo_unref could use a mechanism such as bottom halves to move deallocation +``foo_unref`` could use a mechanism such as bottom halves to move deallocation out of the write-side critical section. RCU resizable arrays --------------------- +^^^^^^^^^^^^^^^^^^^^ Resizable arrays can be used with RCU. The expensive RCU synchronization -(or call_rcu) only needs to take place when the array is resized. +(or ``call_rcu``) only needs to take place when the array is resized. The two items to take care of are: - ensuring that the old version of the array is available between removal @@ -351,10 +339,10 @@ The two items to take care of are: - avoiding mismatches in the read side between the array data and the array size. -The first problem is avoided simply by not using realloc. Instead, +The first problem is avoided simply by not using ``realloc``. Instead, each resize will allocate a new array and copy the old data into it. The second problem would arise if the size and the data pointers were -two members of a larger struct: +two members of a larger struct:: struct mystuff { ... @@ -364,7 +352,7 @@ two members of a larger struct: ... }; -Instead, we store the size of the array with the array itself: +Instead, we store the size of the array with the array itself:: struct arr { int size; @@ -400,7 +388,7 @@ Instead, we store the size of the array with the array itself: } -SOURCES -======= +References +---------- -* Documentation/RCU/ from the Linux kernel +* The `Linux kernel RCU documentation `__ From patchwork Fri Aug 16 13:22:11 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 819738 Delivered-To: patch@linaro.org Received: by 2002:adf:a3c8:0:b0:367:895a:4699 with SMTP id m8csp286751wrb; Fri, 16 Aug 2024 06:23:59 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCV67dhIMrt8cwI9fcehzYKAZV1XY8iO9Zv9ECllO4az0l1TpgVE14A/EQaIKTh4Nu0aa5gg1bvkx65vEGN77IwN X-Google-Smtp-Source: AGHT+IGK1IWGb/5inI429lFMYzIVdAr4/E3lo2AGbQ6qROark69qt/bByHqj13R3yxsdTEBnLOqs X-Received: by 2002:a05:622a:598a:b0:441:5a0c:41d9 with SMTP id d75a77b69052e-45374311900mr20857811cf.36.1723814639128; Fri, 16 Aug 2024 06:23:59 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1723814639; cv=none; d=google.com; s=arc-20160816; b=fs9z5/lFlA7lp49Lhx9UP3wtkQpgfrh4JlTnfmk+jDFbybl6+I2e5jEk0t9a68RMVj No/Bqs/flue+Q/49a06Ocvf+blzEnilj4vs07Qt4Dycf8Zg8uC6lYFgAvGZbmUjW9ejk htyJIziFCjNntFx9xn2orG/q+cuvhac6ZlKWb9Vvc2gYpzlwJkZodkPZdrRaySmoTlmK aNdkf+pptPP4VD57X4NkAkJpXVSk8U4NZynZc4kWbB0S4GTxWLAeOyEfbKx/45nBkn3F Hd1ZPWQmuyfiZwm/HR1M8l+XuMai3MHpSxMWI9zcsIzTDxSpaUOPf7FFym607jjQRZrO Zs7Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=tbFKdbxYbnOhLfqgIpN9vAb16GVhlAA5iH79ZtRgaj8=; fh=NVInRNxxVvpKCXHA+YUXRIpSUGsR0gcBKdN/9cCMaL0=; b=Uj5JnHcf5ZpM+gffpiR2gN0UICdO3YPvzFZ/hFX8mnHrLa6JeXSktHkaWAMP6fLvVa 1i9hoUqunVMkrxZ0L6IX6FPjkAU6ZDKk48qugQOb8ToTzEYpRLSE09Z7v2xKGwgnfRcu cGtScj9wmvQEi9znuzrFq4dqpZJ0V8arYi70g2GRSEVzGStouEHRpTtA/0TQD1dvpNnb W4NuvrBR3XGTV3tdeHEYM/MkydxmGTJSUANPk5F56uBKFPgk2tJGSZCZZBA9BofNOMNh drJrKcvd4Ebj+HO0r7q0r8gwx1qGOoM+ko8/8q00VkPz73Z6D+qQ6G5XJicrNV1SFKmV p3zQ==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=Dj9mRKkw; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org; dara=neutral header.i=@linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id d75a77b69052e-4536a08ec24si39791091cf.462.2024.08.16.06.23.58 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Fri, 16 Aug 2024 06:23:59 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=Dj9mRKkw; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org; dara=neutral header.i=@linaro.org Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sewuR-0005Wv-T0; Fri, 16 Aug 2024 09:22:27 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sewuM-0005EY-La for qemu-devel@nongnu.org; Fri, 16 Aug 2024 09:22:25 -0400 Received: from mail-wm1-x32e.google.com ([2a00:1450:4864:20::32e]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1sewuK-0007kd-50 for qemu-devel@nongnu.org; Fri, 16 Aug 2024 09:22:22 -0400 Received: by mail-wm1-x32e.google.com with SMTP id 5b1f17b1804b1-42816ca782dso14897415e9.2 for ; Fri, 16 Aug 2024 06:22:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1723814539; x=1724419339; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=tbFKdbxYbnOhLfqgIpN9vAb16GVhlAA5iH79ZtRgaj8=; b=Dj9mRKkwOdmGubtl7nJltjaSORRqagS7qtH1KIoSJNcQ0qQpFe8lURqD+l483ewK+G WaGBw+wn9APLCnOlGi5xPDQEJbjV8YYx23tJE4GHPD7HRoCAVNwplHWgCbfY2U/JS9FK 1B8zjXKXGhmY0z/J98XN/b9AwXITeWNIu9xlm+JuNGyB+liwe1h8z1o4FmPx8FVOmm6e aHK7JMl+k+eINFPKiLU+uvREbDjfdXZZzjG2Gy0ysB3hEVOxWeGJrNUHDeRblx0ByH86 cpnYWPbV256gd+wulRRqtMAfsPPq4GPJfqjDi67BgnoF97Dnrun/MUxTcfURftBtzxRQ eHsA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1723814539; x=1724419339; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=tbFKdbxYbnOhLfqgIpN9vAb16GVhlAA5iH79ZtRgaj8=; b=brMYq/kVX3iieGRnmg9UQw3/IjZBphvSednGZj2d16N3GJPwroT8khPzWjOXvuQiBt lL7XZzBbEI1jubTJ+/rvennvUFUb0VzT2pxEUoPZtS9zchMljdIeOgwvjn96naGh1z0t 7d0v/rgfV5herf0MxpYy678SDxJg/05/RIqYbCUf1J69XAi/neuzsMbMYY//HIGgBPI7 H2K/XNylXDzJ5nFgZ2Xlr8Vs//A1A0jSNiHBRFce9Ei+/iykFSQiXWNlV2DHk2cv+5h6 gmLs4r+q8DAkophbkW4tPOkjgdOwGSoFIp85IdoHZebj1P+lOBjulQ+/+Hri6veC48/m MzWQ== X-Gm-Message-State: AOJu0YzrDbLLZ2cADwOMo5NuQp9N9WICY60q04J4aA+AmSXTGK12KEy5 K1WRCcf4S0vX1SD09nsypniCj32c2B43V+j8oWCCYzj5E22cCoxS7vC2rqGDlKaR2gaJNuTqvGX 3 X-Received: by 2002:a05:6000:1365:b0:367:980a:6aa with SMTP id ffacd0b85a97d-371946bf62dmr2252621f8f.54.1723814538477; Fri, 16 Aug 2024 06:22:18 -0700 (PDT) Received: from orth.archaic.org.uk (orth.archaic.org.uk. [2001:8b0:1d0::2]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-371898ab855sm3631948f8f.105.2024.08.16.06.22.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 16 Aug 2024 06:22:18 -0700 (PDT) From: Peter Maydell To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Kevin Wolf , Hanna Reitz , Stefan Hajnoczi Subject: [PATCH 6/7] include: Move QemuLockCnt APIs to their own header Date: Fri, 16 Aug 2024 14:22:11 +0100 Message-Id: <20240816132212.3602106-7-peter.maydell@linaro.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240816132212.3602106-1-peter.maydell@linaro.org> References: <20240816132212.3602106-1-peter.maydell@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::32e; envelope-from=peter.maydell@linaro.org; helo=mail-wm1-x32e.google.com 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, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: qemu-devel-bounces+patch=linaro.org@nongnu.org Currently the QemuLockCnt data structure and associated functions are in the include/qemu/thread.h header. Move them to their own qemu/lockcnt.h. The main reason for doing this is that it means we can autogenerate the documentation comments into the docs/devel documentation. The copyright/author in the new header is drawn from lockcnt.c, since the header changes were added in the same commit as lockcnt.c; since neither thread.h nor lockcnt.c state an explicit license, the standard default of GPL-2-or-later applies. We include the new header (and the .c file, which was accidentally omitted previously) in the "RCU" part of MAINTAINERS, since that is where the lockcnt.rst documentation is categorized. Signed-off-by: Peter Maydell Reviewed-by: Philippe Mathieu-Daudé Acked-by: Paolo Bonzini --- Paolo: could you confirm that you meant GPL2+ for this code? --- MAINTAINERS | 2 + docs/devel/lockcnt.rst | 2 +- include/block/aio.h | 1 + include/hw/core/cpu.h | 1 + include/qemu/lockcnt.h | 130 +++++++++++++++++++++++++++++++++++++++++ include/qemu/thread.h | 111 ----------------------------------- accel/accel-blocker.c | 1 + hw/core/cpu-common.c | 1 + util/aio-posix.c | 1 + util/aio-win32.c | 1 + util/async.c | 1 + util/fdmon-epoll.c | 1 + util/lockcnt.c | 1 + 13 files changed, 142 insertions(+), 112 deletions(-) create mode 100644 include/qemu/lockcnt.h diff --git a/MAINTAINERS b/MAINTAINERS index f8f4df44460..2da11411ff3 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3115,8 +3115,10 @@ S: Maintained F: docs/devel/lockcnt.rst F: docs/devel/rcu.rst F: include/qemu/rcu*.h +F: include/qemu/lockcnt.h F: tests/unit/rcutorture.c F: tests/unit/test-rcu-*.c +F: util/lockcnt.c F: util/rcu.c Human Monitor (HMP) diff --git a/docs/devel/lockcnt.rst b/docs/devel/lockcnt.rst index 994aeb57151..728594bcea3 100644 --- a/docs/devel/lockcnt.rst +++ b/docs/devel/lockcnt.rst @@ -175,7 +175,7 @@ three instructions in the critical path, two assignments and a ``smp_wmb()``. ``QemuLockCnt`` API ------------------- -The ``QemuLockCnt`` API is described in ``include/qemu/thread.h``. +The ``QemuLockCnt`` API is described in ``include/qemu/lockcnt.h``. ``QemuLockCnt`` usage diff --git a/include/block/aio.h b/include/block/aio.h index 4ee81936ed5..43883a8a33a 100644 --- a/include/block/aio.h +++ b/include/block/aio.h @@ -20,6 +20,7 @@ #include "qemu/coroutine-core.h" #include "qemu/queue.h" #include "qemu/event_notifier.h" +#include "qemu/lockcnt.h" #include "qemu/thread.h" #include "qemu/timer.h" #include "block/graph-lock.h" diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h index 1c9c775df65..ecbeeb1c0dd 100644 --- a/include/hw/core/cpu.h +++ b/include/hw/core/cpu.h @@ -33,6 +33,7 @@ #include "qemu/bitmap.h" #include "qemu/rcu_queue.h" #include "qemu/queue.h" +#include "qemu/lockcnt.h" #include "qemu/thread.h" #include "qom/object.h" diff --git a/include/qemu/lockcnt.h b/include/qemu/lockcnt.h new file mode 100644 index 00000000000..2c92ae17c9e --- /dev/null +++ b/include/qemu/lockcnt.h @@ -0,0 +1,130 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * QemuLockCnt implementation + * + * Copyright Red Hat, Inc. 2017 + * + * Author: + * Paolo Bonzini + * + */ + +#ifndef QEMU_LOCKCNT_H +#define QEMU_LOCKCNT_H + +#include "qemu/thread.h" + +typedef struct QemuLockCnt QemuLockCnt; + +struct QemuLockCnt { +#ifndef CONFIG_LINUX + QemuMutex mutex; +#endif + unsigned count; +}; + +/** + * qemu_lockcnt_init: initialize a QemuLockcnt + * @lockcnt: the lockcnt to initialize + * + * Initialize lockcnt's counter to zero and prepare its mutex + * for usage. + */ +void qemu_lockcnt_init(QemuLockCnt *lockcnt); + +/** + * qemu_lockcnt_destroy: destroy a QemuLockcnt + * @lockcnt: the lockcnt to destruct + * + * Destroy lockcnt's mutex. + */ +void qemu_lockcnt_destroy(QemuLockCnt *lockcnt); + +/** + * qemu_lockcnt_inc: increment a QemuLockCnt's counter + * @lockcnt: the lockcnt to operate on + * + * If the lockcnt's count is zero, wait for critical sections + * to finish and increment lockcnt's count to 1. If the count + * is not zero, just increment it. + * + * Because this function can wait on the mutex, it must not be + * called while the lockcnt's mutex is held by the current thread. + * For the same reason, qemu_lockcnt_inc can also contribute to + * AB-BA deadlocks. This is a sample deadlock scenario: + * + * thread 1 thread 2 + * ------------------------------------------------------- + * qemu_lockcnt_lock(&lc1); + * qemu_lockcnt_lock(&lc2); + * qemu_lockcnt_inc(&lc2); + * qemu_lockcnt_inc(&lc1); + */ +void qemu_lockcnt_inc(QemuLockCnt *lockcnt); + +/** + * qemu_lockcnt_dec: decrement a QemuLockCnt's counter + * @lockcnt: the lockcnt to operate on + */ +void qemu_lockcnt_dec(QemuLockCnt *lockcnt); + +/** + * qemu_lockcnt_dec_and_lock: decrement a QemuLockCnt's counter and + * possibly lock it. + * @lockcnt: the lockcnt to operate on + * + * Decrement lockcnt's count. If the new count is zero, lock + * the mutex and return true. Otherwise, return false. + */ +bool qemu_lockcnt_dec_and_lock(QemuLockCnt *lockcnt); + +/** + * qemu_lockcnt_dec_if_lock: possibly decrement a QemuLockCnt's counter and + * lock it. + * @lockcnt: the lockcnt to operate on + * + * If the count is 1, decrement the count to zero, lock + * the mutex and return true. Otherwise, return false. + */ +bool qemu_lockcnt_dec_if_lock(QemuLockCnt *lockcnt); + +/** + * qemu_lockcnt_lock: lock a QemuLockCnt's mutex. + * @lockcnt: the lockcnt to operate on + * + * Remember that concurrent visits are not blocked unless the count is + * also zero. You can use qemu_lockcnt_count to check for this inside a + * critical section. + */ +void qemu_lockcnt_lock(QemuLockCnt *lockcnt); + +/** + * qemu_lockcnt_unlock: release a QemuLockCnt's mutex. + * @lockcnt: the lockcnt to operate on. + */ +void qemu_lockcnt_unlock(QemuLockCnt *lockcnt); + +/** + * qemu_lockcnt_inc_and_unlock: combined unlock/increment on a QemuLockCnt. + * @lockcnt: the lockcnt to operate on. + * + * This is the same as + * + * qemu_lockcnt_unlock(lockcnt); + * qemu_lockcnt_inc(lockcnt); + * + * but more efficient. + */ +void qemu_lockcnt_inc_and_unlock(QemuLockCnt *lockcnt); + +/** + * qemu_lockcnt_count: query a LockCnt's count. + * @lockcnt: the lockcnt to query. + * + * Note that the count can change at any time. Still, while the + * lockcnt is locked, one can usefully check whether the count + * is non-zero. + */ +unsigned qemu_lockcnt_count(QemuLockCnt *lockcnt); + +#endif diff --git a/include/qemu/thread.h b/include/qemu/thread.h index fb74e21c08a..7eba27a7049 100644 --- a/include/qemu/thread.h +++ b/include/qemu/thread.h @@ -293,115 +293,4 @@ static inline void qemu_spin_unlock(QemuSpin *spin) #endif } -struct QemuLockCnt { -#ifndef CONFIG_LINUX - QemuMutex mutex; -#endif - unsigned count; -}; - -/** - * qemu_lockcnt_init: initialize a QemuLockcnt - * @lockcnt: the lockcnt to initialize - * - * Initialize lockcnt's counter to zero and prepare its mutex - * for usage. - */ -void qemu_lockcnt_init(QemuLockCnt *lockcnt); - -/** - * qemu_lockcnt_destroy: destroy a QemuLockcnt - * @lockcnt: the lockcnt to destruct - * - * Destroy lockcnt's mutex. - */ -void qemu_lockcnt_destroy(QemuLockCnt *lockcnt); - -/** - * qemu_lockcnt_inc: increment a QemuLockCnt's counter - * @lockcnt: the lockcnt to operate on - * - * If the lockcnt's count is zero, wait for critical sections - * to finish and increment lockcnt's count to 1. If the count - * is not zero, just increment it. - * - * Because this function can wait on the mutex, it must not be - * called while the lockcnt's mutex is held by the current thread. - * For the same reason, qemu_lockcnt_inc can also contribute to - * AB-BA deadlocks. This is a sample deadlock scenario: - * - * thread 1 thread 2 - * ------------------------------------------------------- - * qemu_lockcnt_lock(&lc1); - * qemu_lockcnt_lock(&lc2); - * qemu_lockcnt_inc(&lc2); - * qemu_lockcnt_inc(&lc1); - */ -void qemu_lockcnt_inc(QemuLockCnt *lockcnt); - -/** - * qemu_lockcnt_dec: decrement a QemuLockCnt's counter - * @lockcnt: the lockcnt to operate on - */ -void qemu_lockcnt_dec(QemuLockCnt *lockcnt); - -/** - * qemu_lockcnt_dec_and_lock: decrement a QemuLockCnt's counter and - * possibly lock it. - * @lockcnt: the lockcnt to operate on - * - * Decrement lockcnt's count. If the new count is zero, lock - * the mutex and return true. Otherwise, return false. - */ -bool qemu_lockcnt_dec_and_lock(QemuLockCnt *lockcnt); - -/** - * qemu_lockcnt_dec_if_lock: possibly decrement a QemuLockCnt's counter and - * lock it. - * @lockcnt: the lockcnt to operate on - * - * If the count is 1, decrement the count to zero, lock - * the mutex and return true. Otherwise, return false. - */ -bool qemu_lockcnt_dec_if_lock(QemuLockCnt *lockcnt); - -/** - * qemu_lockcnt_lock: lock a QemuLockCnt's mutex. - * @lockcnt: the lockcnt to operate on - * - * Remember that concurrent visits are not blocked unless the count is - * also zero. You can use qemu_lockcnt_count to check for this inside a - * critical section. - */ -void qemu_lockcnt_lock(QemuLockCnt *lockcnt); - -/** - * qemu_lockcnt_unlock: release a QemuLockCnt's mutex. - * @lockcnt: the lockcnt to operate on. - */ -void qemu_lockcnt_unlock(QemuLockCnt *lockcnt); - -/** - * qemu_lockcnt_inc_and_unlock: combined unlock/increment on a QemuLockCnt. - * @lockcnt: the lockcnt to operate on. - * - * This is the same as - * - * qemu_lockcnt_unlock(lockcnt); - * qemu_lockcnt_inc(lockcnt); - * - * but more efficient. - */ -void qemu_lockcnt_inc_and_unlock(QemuLockCnt *lockcnt); - -/** - * qemu_lockcnt_count: query a LockCnt's count. - * @lockcnt: the lockcnt to query. - * - * Note that the count can change at any time. Still, while the - * lockcnt is locked, one can usefully check whether the count - * is non-zero. - */ -unsigned qemu_lockcnt_count(QemuLockCnt *lockcnt); - #endif diff --git a/accel/accel-blocker.c b/accel/accel-blocker.c index e083f24aa80..75daaa29113 100644 --- a/accel/accel-blocker.c +++ b/accel/accel-blocker.c @@ -25,6 +25,7 @@ */ #include "qemu/osdep.h" +#include "qemu/lockcnt.h" #include "qemu/thread.h" #include "qemu/main-loop.h" #include "hw/core/cpu.h" diff --git a/hw/core/cpu-common.c b/hw/core/cpu-common.c index 7982ecd39a5..09c79035949 100644 --- a/hw/core/cpu-common.c +++ b/hw/core/cpu-common.c @@ -24,6 +24,7 @@ #include "sysemu/hw_accel.h" #include "qemu/log.h" #include "qemu/main-loop.h" +#include "qemu/lockcnt.h" #include "exec/log.h" #include "exec/gdbstub.h" #include "sysemu/tcg.h" diff --git a/util/aio-posix.c b/util/aio-posix.c index 266c9dd35fa..06bf9f456cf 100644 --- a/util/aio-posix.c +++ b/util/aio-posix.c @@ -17,6 +17,7 @@ #include "block/block.h" #include "block/thread-pool.h" #include "qemu/main-loop.h" +#include "qemu/lockcnt.h" #include "qemu/rcu.h" #include "qemu/rcu_queue.h" #include "qemu/sockets.h" diff --git a/util/aio-win32.c b/util/aio-win32.c index d144f9391fb..6583d5c5f31 100644 --- a/util/aio-win32.c +++ b/util/aio-win32.c @@ -18,6 +18,7 @@ #include "qemu/osdep.h" #include "block/block.h" #include "qemu/main-loop.h" +#include "qemu/lockcnt.h" #include "qemu/queue.h" #include "qemu/sockets.h" #include "qapi/error.h" diff --git a/util/async.c b/util/async.c index 3e3e4fc7126..99db28389f6 100644 --- a/util/async.c +++ b/util/async.c @@ -30,6 +30,7 @@ #include "block/graph-lock.h" #include "qemu/main-loop.h" #include "qemu/atomic.h" +#include "qemu/lockcnt.h" #include "qemu/rcu_queue.h" #include "block/raw-aio.h" #include "qemu/coroutine_int.h" diff --git a/util/fdmon-epoll.c b/util/fdmon-epoll.c index c6413cb18fe..9fb8800dde8 100644 --- a/util/fdmon-epoll.c +++ b/util/fdmon-epoll.c @@ -5,6 +5,7 @@ #include "qemu/osdep.h" #include +#include "qemu/lockcnt.h" #include "qemu/rcu_queue.h" #include "aio-posix.h" diff --git a/util/lockcnt.c b/util/lockcnt.c index 5da36946b1b..d07c6cc5cee 100644 --- a/util/lockcnt.c +++ b/util/lockcnt.c @@ -7,6 +7,7 @@ * Paolo Bonzini */ #include "qemu/osdep.h" +#include "qemu/lockcnt.h" #include "qemu/thread.h" #include "qemu/atomic.h" #include "trace.h" From patchwork Fri Aug 16 13:22:12 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 819735 Delivered-To: patch@linaro.org Received: by 2002:adf:a3c8:0:b0:367:895a:4699 with SMTP id m8csp286176wrb; Fri, 16 Aug 2024 06:23:02 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCWgMkfzaaYlhRSJJvAD9o64F97qTbAGRccZ96Ry2zefLQex1eCkv6x45dvtjLQVtS2mMalS2PGE6yIRnbG/ZFUE X-Google-Smtp-Source: AGHT+IG2tUzHX7xq5fLR4vWggAxqIydydXQH0P7ZScxsKoLxUWTDAWmqr+W0tnkHK2rQf+6UCixz X-Received: by 2002:a05:6214:41a0:b0:6b5:dcda:bada with SMTP id 6a1803df08f44-6bf7cf15f7dmr30717836d6.55.1723814582402; Fri, 16 Aug 2024 06:23:02 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1723814582; cv=none; d=google.com; s=arc-20160816; b=vjnjn1bRgy42QLjnCAohiNQDh7AiujQ9UOx4nrYPy0lNWHHGmGcmA5hxPE8elhyL8g AS8TDSmXSXG6/fTZAGBUKJyBbTdSLEH9Z5gV7bDtCDaThe7WZEsW93LP5M9I3DLB88rj +2xb9jTHoW93K71Yw/gFobEFQKPp//lecLHTdmCmHEXJtRPZ4M+QdO2SaXCpocnC9HGu HCF35JLXCF+5T2LiiNKDX5b/bzfiQD7H9xAGMzvXQMQDp+sX+YdGdAuyD2FImMdqLAiR DaG+78fKIuoM1/Px6BBlCkyT4ZZN667x9UaSaET1tQ8d9hmtZrL8q1r92daNtlvWtvu6 Di4w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=2vFh0taXho/PjkpHjQyE36dh+SvBwU6eZKgiDGqrkEc=; fh=NVInRNxxVvpKCXHA+YUXRIpSUGsR0gcBKdN/9cCMaL0=; b=ILeqFrI2zU54/wM86EZ08BJikLzYKHeZHuMqlTnLJCJJm1h6QKs+bnX+4wrAGwb2ZZ JEbrArxdL0DJHv9y6qPMJijA5wu1UjEyLs4BKljW1k1QpUNwbYz9S5O+Xh3xFl2tGJG1 f+zdlIXm7mzpzgbUC1dfiYuwc1qgw3jEV26kL7G+TGJ3+fug/YtxmUmv9f5E3SriHAnW mBI/IwJIforCPMpQLc7/hYzO6WfeZ3NXa8bjoET+3nzQ9Dmh4cxE9iuXCKaaogX0YaLt ysGX6wiM27T89o+JxCxJEC7+Mzt17FYAG6t/PE03Pn/T9G7Hvz68xpNnUxCFlSJWSmQW qWOg==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=UEv4R0fK; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org; dara=neutral header.i=@linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id 6a1803df08f44-6bf6ff24450si40269266d6.507.2024.08.16.06.23.02 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Fri, 16 Aug 2024 06:23:02 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=UEv4R0fK; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org; dara=neutral header.i=@linaro.org Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sewuT-0005dR-Ir; Fri, 16 Aug 2024 09:22:30 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sewuN-0005Gv-8u for qemu-devel@nongnu.org; Fri, 16 Aug 2024 09:22:25 -0400 Received: from mail-wm1-x32d.google.com ([2a00:1450:4864:20::32d]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1sewuK-0007ki-TR for qemu-devel@nongnu.org; Fri, 16 Aug 2024 09:22:23 -0400 Received: by mail-wm1-x32d.google.com with SMTP id 5b1f17b1804b1-428ec6c190eso14950045e9.1 for ; Fri, 16 Aug 2024 06:22:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1723814539; x=1724419339; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=2vFh0taXho/PjkpHjQyE36dh+SvBwU6eZKgiDGqrkEc=; b=UEv4R0fK1fD2+IcqqzEhOY+HRTxO/MHpZp7CFHeXHtkVG2Inwc2FNTzDDUrSDV2rCp yBLqLYIqr0P1p76qzhEHme0U4bk+7jpcJqtMkzlnLPqfAJ7SEMPg4Fzs1FjHofVZmAB6 LWsQphDDhHiX0VLHBBfPTxhW2KKqUEyTaGGaHe0r9445Fmmha2nPpooVyoJr42dMAHSq I7/UUVZVPdG++fvlRzYB8BrFsDOSbgM77eQVqgcHbUwKdXTQd9zdHRt7TBHTKIkP0HTr CPWEVX66dvboqAK/aV9mOzQgRJQfI1d6pr5xal1Uk4ByWNYOvN9/Es3hcWUf+70dmOWX 7lVg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1723814539; x=1724419339; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=2vFh0taXho/PjkpHjQyE36dh+SvBwU6eZKgiDGqrkEc=; b=NMPsmi0Rg1EsUwfelgOEvxUZimaGrK0q4l7G1x+tHmPhNsjlIAP3/u1nBOciZ1N2bl rGGyda6xvZzBxPXTHJ926VKQCzn7/VDBYAyeauKGiNEUCh1MYGyAgwj+bkVPO2taXcje boTQ0Kua6ZKEsgwaBCd4cRUtVt1Oi81xK62tcO4SVMQIv+ArRlo8YWZXZ46bQIs3fKth QwMOGcudVRj0i12wpYFeLePo7IuzWud/P47+nO1CFW7Y/1Ox2wvD1yiyLMVRwYUeTFo2 /7/d0Jy9wZcws8e58Ji39L3UTxDeU6CZ5T+Ho7t9AW9FPEBB2ipQBnhFK0moT0Y2/ahX QYkQ== X-Gm-Message-State: AOJu0YygDE58M4ahfg6RxumB3SmLqW+QBf+SXsgVaJhepw82JLoBFj6e ZGhzIRfWFWa+ZsuW2CP9S6/fnOEb3Uol9UTX2er3pDLQpxAwuroMblpAL1Q0io/Q2qWNj906GNw t X-Received: by 2002:adf:fa50:0:b0:371:72a8:15e with SMTP id ffacd0b85a97d-371943292ecmr1600973f8f.16.1723814539070; Fri, 16 Aug 2024 06:22:19 -0700 (PDT) Received: from orth.archaic.org.uk (orth.archaic.org.uk. [2001:8b0:1d0::2]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-371898ab855sm3631948f8f.105.2024.08.16.06.22.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 16 Aug 2024 06:22:18 -0700 (PDT) From: Peter Maydell To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Kevin Wolf , Hanna Reitz , Stefan Hajnoczi Subject: [PATCH 7/7] docs/devel/lockcnt: Include kernel-doc API documentation Date: Fri, 16 Aug 2024 14:22:12 +0100 Message-Id: <20240816132212.3602106-8-peter.maydell@linaro.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240816132212.3602106-1-peter.maydell@linaro.org> References: <20240816132212.3602106-1-peter.maydell@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::32d; envelope-from=peter.maydell@linaro.org; helo=mail-wm1-x32d.google.com 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, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: qemu-devel-bounces+patch=linaro.org@nongnu.org Pull in the kernel-doc API documentation into the lockcnt docs. This requires us to fix one rST markup syntax error in the header file comments. Signed-off-by: Peter Maydell --- docs/devel/lockcnt.rst | 2 +- include/qemu/lockcnt.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/devel/lockcnt.rst b/docs/devel/lockcnt.rst index 728594bcea3..8b43578f6c7 100644 --- a/docs/devel/lockcnt.rst +++ b/docs/devel/lockcnt.rst @@ -175,7 +175,7 @@ three instructions in the critical path, two assignments and a ``smp_wmb()``. ``QemuLockCnt`` API ------------------- -The ``QemuLockCnt`` API is described in ``include/qemu/lockcnt.h``. +.. kernel-doc:: include/qemu/lockcnt.h ``QemuLockCnt`` usage diff --git a/include/qemu/lockcnt.h b/include/qemu/lockcnt.h index 2c92ae17c9e..f4b62a3f701 100644 --- a/include/qemu/lockcnt.h +++ b/include/qemu/lockcnt.h @@ -51,7 +51,7 @@ void qemu_lockcnt_destroy(QemuLockCnt *lockcnt); * Because this function can wait on the mutex, it must not be * called while the lockcnt's mutex is held by the current thread. * For the same reason, qemu_lockcnt_inc can also contribute to - * AB-BA deadlocks. This is a sample deadlock scenario: + * AB-BA deadlocks. This is a sample deadlock scenario:: * * thread 1 thread 2 * -------------------------------------------------------