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

Hyman huangy81 at chinatelecom.cn
Wed Jan 13 14:05:44 UTC 2021


在 2021/1/13 21:32, Han Han 写道:
>
>
> On Wed, Jan 13, 2021 at 1:09 AM <huangy81 at chinatelecom.cn 
> <mailto:huangy81 at chinatelecom.cn>> wrote:
>
>     From: Hyman <huangy81 at chinatelecom.cn
>     <mailto: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
>     <mailto: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

indeed, it hasn't been merged.  This patchset base on the following works:

https://lore.kernel.org/qemu-devel/20210108164601.406146-1-peterx@redhat.com/

Maybe the review is under way. I post this patchset for review in 
advance. Once the qemu patchset is merged, i'll ping the libvir-list and 
apply for merging.

>     +   ==============
>     ============================================================================
>     ================================== ============================
>
>      ``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/21f588d4/attachment-0001.htm>


More information about the libvir-list mailing list