[PATCH v3 3/3] qemu: suppor dirty ring feature

Han Han hhan at redhat.com
Wed Jan 13 13:32:24 UTC 2021


On Wed, Jan 13, 2021 at 1:09 AM <huangy81 at chinatelecom.cn> wrote:

> From: Hyman <huangy81 at chinatelecom.cn>
>
> QEMU introduced a dirty ring feature, this patch add a new
> KVM feature 'dirty-ring' to set this feature for kvm guests.
>
> To enable the feature, libvirt add "-accel dirty-gfn-count=xxx"
> to QEMU command line, the following XML needs to be added to
> the guest's domain description:
>
> <features>
>   <kvm>
>     <dirty-ring state='on' size='xxx'>
>   </kvm>
> </features>
>
> Signed-off-by: Hyman <huangy81 at chinatelecom.cn>
> ---
>  docs/formatdomain.rst         | 16 +++++++++-------
>  docs/schemas/domaincommon.rng | 10 ++++++++++
>  src/conf/domain_conf.c        | 34 ++++++++++++++++++++++++++++++++++
>  src/conf/domain_conf.h        |  4 ++++
>  src/qemu/qemu_command.c       | 13 ++++++++++---
>  5 files changed, 67 insertions(+), 10 deletions(-)
>
> diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
> index 6100b88..5bf8517 100644
> --- a/docs/formatdomain.rst
> +++ b/docs/formatdomain.rst
> @@ -1767,6 +1767,7 @@ Hypervisors may allow certain CPU / machine features
> to be toggled on/off.
>         <hidden state='on'/>
>         <hint-dedicated state='on'/>
>         <poll-control='on'/>
> +       <dirty-ring state='on' size='4096'/>
>       </kvm>
>       <xen>
>         <e820_host state='on'/>
> @@ -1849,13 +1850,14 @@ are:
>  ``kvm``
>     Various features to change the behavior of the KVM hypervisor.
>
> -   ==============
> ============================================================================
> ======= ============================
> -   Feature        Description
>                       Value   Since
> -   ==============
> ============================================================================
> ======= ============================
> -   hidden         Hide the KVM hypervisor from standard MSR based
> discovery                    on, off :since:`1.2.8 (QEMU 2.1.0)`
> -   hint-dedicated Allows a guest to enable optimizations when running on
> dedicated vCPUs       on, off :since:`5.7.0 (QEMU 2.12.0)`
> -   poll-control   Decrease IO completion latency by introducing a grace
> period of busy waiting on, off :since:`6.10.0 (QEMU 4.2)`
> -   ==============
> ============================================================================
> ======= ============================
> +   ==============
> ============================================================================
> ================================== ============================
> +   Feature        Description
>                       Value                              Since
> +   ==============
> ============================================================================
> ================================== ============================
> +   hidden         Hide the KVM hypervisor from standard MSR based
> discovery                    on, off
> :since:`1.2.8 (QEMU 2.1.0)`
> +   hint-dedicated Allows a guest to enable optimizations when running on
> dedicated vCPUs       on, off                            :since:`5.7.0
> (QEMU 2.12.0)`
> +   poll-control   Decrease IO completion latency by introducing a grace
> period of busy waiting on, off                            :since:`6.10.0
> (QEMU 4.2)`
> +   dirty-ring     Enable dirty ring feature
>                       on, off; size - must be power of 2 :since:`7.0.0
> (QEMU 5.2.1)`
>
Are you sure it will be added in QEMU 5.2.1 ?
I find it has been not merged in qemu yet

> +   ==============
> ============================================================================
> ================================== ============================
>
>  ``xen``
>     Various features to change the behavior of the Xen hypervisor.
> diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
> index 7dc419b..5af4bbe 100644
> --- a/docs/schemas/domaincommon.rng
> +++ b/docs/schemas/domaincommon.rng
> @@ -6569,6 +6569,16 @@
>              <ref name="featurestate"/>
>            </element>
>          </optional>
> +        <optional>
> +          <element name="dirty-ring">
> +            <ref name="featurestate"/>
> +            <optional>
> +              <attribute name="size">
> +                <data type="unsignedInt"/>
> +              </attribute>
> +            </optional>
> +          </element>
> +        </optional>
>        </interleave>
>      </element>
>    </define>
> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
> index 349fc28..e617b95 100644
> --- a/src/conf/domain_conf.c
> +++ b/src/conf/domain_conf.c
> @@ -186,6 +186,7 @@ VIR_ENUM_IMPL(virDomainKVM,
>                "hidden",
>                "hint-dedicated",
>                "poll-control",
> +              "dirty-ring",
>  );
>
>  VIR_ENUM_IMPL(virDomainXen,
> @@ -18379,6 +18380,7 @@ virDomainFeaturesDefParse(virDomainDefPtr def,
>      if (def->features[VIR_DOMAIN_FEATURE_KVM] == VIR_TRISTATE_SWITCH_ON) {
>          int feature;
>          int value;
> +        node = ctxt->node;
>          if ((n = virXPathNodeSet("./features/kvm/*", ctxt, &nodes)) < 0)
>              return -1;
>
> @@ -18395,6 +18397,7 @@ virDomainFeaturesDefParse(virDomainDefPtr def,
>                  case VIR_DOMAIN_KVM_HIDDEN:
>                  case VIR_DOMAIN_KVM_DEDICATED:
>                  case VIR_DOMAIN_KVM_POLLCONTROL:
> +                case VIR_DOMAIN_KVM_DIRTY_RING:
>                      if (!(tmp = virXMLPropString(nodes[i], "state"))) {
>                          virReportError(VIR_ERR_XML_ERROR,
>                                         _("missing 'state' attribute for "
> @@ -18413,6 +18416,26 @@ virDomainFeaturesDefParse(virDomainDefPtr def,
>
>                      VIR_FREE(tmp);
>                      def->kvm_features[feature] = value;
> +
> +                    /* only for dirty ring case */
> +                    if (((virDomainKVM) feature) ==
> VIR_DOMAIN_KVM_DIRTY_RING &&
> +                          value == VIR_TRISTATE_SWITCH_ON) {
> +                        ctxt->node = nodes[i];
> +                        if (virXPathUInt("string(./@size)", ctxt,
> +                                         &def->dirty_gfn_count) < 0) {
> +                            virReportError(VIR_ERR_XML_ERROR, "%s",
> +                                           _("invalid number of dirty
> GFNs"));
> +                            return -1;
> +                        }
> +
> +                        if ((def->dirty_gfn_count & (def->dirty_gfn_count
> - 1)) ||
> +                            def->dirty_gfn_count > 65536) {
> +                            virReportError(VIR_ERR_XML_ERROR, "%s",
> +                                           _("max number of dirty GFNs is
> 65536 "
> +                                             "and must be power of 2"));
> +                            return -1;
> +                        }
> +                    }
>                      break;
>
>                  /* coverity[dead_error_begin] */
> @@ -18421,6 +18444,7 @@ virDomainFeaturesDefParse(virDomainDefPtr def,
>              }
>          }
>          VIR_FREE(nodes);
> +        ctxt->node = node;
>      }
>
>      if (def->features[VIR_DOMAIN_FEATURE_XEN] == VIR_TRISTATE_SWITCH_ON) {
> @@ -22521,6 +22545,7 @@
> virDomainDefFeaturesCheckABIStability(virDomainDefPtr src,
>              case VIR_DOMAIN_KVM_HIDDEN:
>              case VIR_DOMAIN_KVM_DEDICATED:
>              case VIR_DOMAIN_KVM_POLLCONTROL:
> +            case VIR_DOMAIN_KVM_DIRTY_RING:
>                  if (src->kvm_features[i] != dst->kvm_features[i]) {
>                      virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
>                                     _("State of KVM feature '%s' differs: "
> @@ -28271,6 +28296,15 @@ virDomainDefFormatFeatures(virBufferPtr buf,
>                                                def->kvm_features[j]));
>                      break;
>
> +                case VIR_DOMAIN_KVM_DIRTY_RING:
> +                    if (def->kvm_features[j])
> +                        virBufferAsprintf(&childBuf, "<%s state='%s'
> size='%d'/>\n",
> +                                          virDomainKVMTypeToString(j),
> +                                          virTristateSwitchTypeToString(
> +                                              def->kvm_features[j]),
> +                                          def->dirty_gfn_count);
> +                    break;
> +
>                  /* coverity[dead_error_begin] */
>                  case VIR_DOMAIN_KVM_LAST:
>                      break;
> diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
> index ec43bbe..120d490 100644
> --- a/src/conf/domain_conf.h
> +++ b/src/conf/domain_conf.h
> @@ -1917,6 +1917,7 @@ typedef enum {
>      VIR_DOMAIN_KVM_HIDDEN = 0,
>      VIR_DOMAIN_KVM_DEDICATED,
>      VIR_DOMAIN_KVM_POLLCONTROL,
> +    VIR_DOMAIN_KVM_DIRTY_RING,
>
>      VIR_DOMAIN_KVM_LAST
>  } virDomainKVM;
> @@ -2728,6 +2729,9 @@ struct _virDomainDef {
>                               callbacks failed for a non-critical reason
>                               (was not able to fill in some data) and thus
>                               should be re-run before starting */
> +
> +    /* Number of dirty GFNs per ring */
> +    unsigned int dirty_gfn_count;
>  };
>
>
> diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
> index 0f660aa..31829ba 100644
> --- a/src/qemu/qemu_command.c
> +++ b/src/qemu/qemu_command.c
> @@ -6525,6 +6525,9 @@ qemuBuildCpuCommandLine(virCommandPtr cmd,
>                      virBufferAddLit(&buf, ",kvm-poll-control=on");
>                  break;
>
> +            case VIR_DOMAIN_KVM_DIRTY_RING:
> +                break;
> +
>              /* coverity[dead_error_begin] */
>              case VIR_DOMAIN_KVM_LAST:
>                  break;
> @@ -6959,9 +6962,13 @@ qemuBuildAccelCommandLineTcgOptions(void)
>
>
>  static void
> -qemuBuildAccelCommandLineKvmOptions(void)
> +qemuBuildAccelCommandLineKvmOptions(virBuffer *buf,
> +                                    const virDomainDef *def)
>  {
> -    /* implemented in the next patch */
> +    if (def->features[VIR_DOMAIN_FEATURE_KVM] == VIR_TRISTATE_SWITCH_ON &&
> +        def->kvm_features[VIR_DOMAIN_KVM_DIRTY_RING] ==
> VIR_TRISTATE_SWITCH_ON) {
> +        virBufferAsprintf(buf, ",dirty-gfn-count=%d",
> def->dirty_gfn_count);
> +    }
>  }
>
>
> @@ -6982,7 +6989,7 @@ qemuBuildAccelCommandLine(virCommandPtr cmd,
>
>      case VIR_DOMAIN_VIRT_KVM:
>          virBufferAddLit(&buf, "kvm");
> -        qemuBuildAccelCommandLineKvmOptions();
> +        qemuBuildAccelCommandLineKvmOptions(&buf, def);
>          break;
>
>      case VIR_DOMAIN_VIRT_KQEMU:
> --
> 1.8.3.1
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20210113/e79c7822/attachment-0001.htm>


More information about the libvir-list mailing list