From mboxrd@z Thu Jan 1 00:00:00 1970 From: Radim =?utf-8?B?S3LEjW3DocWZ?= Subject: Re: [PATCH 1/2] KVM: page track: add a new notifier type: track_flush_slot Date: Wed, 12 Oct 2016 22:48:27 +0200 Message-ID: <20161012204827.GA15270@potion> References: <1475998904-13456-1-git-send-email-xiaoguang.chen@intel.com> <1475998904-13456-2-git-send-email-xiaoguang.chen@intel.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Cc: kvm@vger.kernel.org, pbonzini@redhat.com, guangrong.xiao@intel.com, jike.song@intel.com To: Xiaoguang Chen Return-path: Received: from mx1.redhat.com ([209.132.183.28]:50778 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S934110AbcJLUsb (ORCPT ); Wed, 12 Oct 2016 16:48:31 -0400 Content-Disposition: inline In-Reply-To: <1475998904-13456-2-git-send-email-xiaoguang.chen@intel.com> Sender: kvm-owner@vger.kernel.org List-ID: 2016-10-09 15:41+0800, Xiaoguang Chen: > When a memory slot is being moved or removed users of page track > can be notified. So users can drop write-protection for the pages > in that memory slot. > > This notifier type is needed by KVMGT to sync up its shadow page > table when memory slot is being moved or removed. > > Reviewed-by: Xiao Guangrong > Signed-off-by: Chen Xiaoguang > --- > diff --git a/arch/x86/kvm/page_track.c b/arch/x86/kvm/page_track.c > @@ -225,3 +225,28 @@ void kvm_page_track_write(struct kvm_vcpu *vcpu, gpa_t gpa, const u8 *new, > + > +/* > + * Notify the node that memory slot is being removed or moved so that it can > + * drop write-protection for the pages in the memory slot. > + * > + * The node should figure out it has any write-protected pages in this slot > + * by itself. > + */ > +void kvm_page_track_flush_slot(struct kvm *kvm, struct kvm_memory_slot *slot) > +{ > + struct kvm_page_track_notifier_head *head; > + struct kvm_page_track_notifier_node *n; > + int idx; > + > + head = &kvm->arch.track_notifier_head; > + > + if (hlist_empty(&head->track_notifier_list)) > + return; > + > + idx = srcu_read_lock(&head->track_srcu); > + hlist_for_each_entry_rcu(n, &head->track_notifier_list, node) > + if (n->track_flush_slot) > + n->track_flush_slot(kvm, slot); > + srcu_read_unlock(&head->track_srcu, idx); > +} We repeat the same drill for the other page_track_notifier as well ... I was thinking it would be nice to have something like: void kvm_page_track_flush_slot(struct kvm *kvm, struct kvm_memory_slot *slot) { struct kvm_page_track_notifier_node *n; int i; kvm_for_each_track_notifier(n, &kvm->arch.track_notifier_head, i) if (n->track_flush_slot) n->track_flush_slot(kvm, slot); } which requires this monster: #define kvm_for_each_track_notifier(notifier, head, tmp) \ for (tmp = !hlist_empty(&(head)->track_notifier_list); \ tmp && ({tmp = srcu_read_lock(&(head)->track_srcu); true;}); \ srcu_read_unlock(&(head)->track_srcu, tmp), tmp = 0) \ hlist_for_each_entry_rcu(notifier, &(head)->track_notifier_list, node) so waiting for more notifiers doesn't seem that bad. :)