On Wed, Dec 01, 2021, Maciej S. Szmigiero wrote: > On 01.12.2021 04:41, Sean Christopherson wrote: > > On Tue, Nov 30, 2021, Maciej S. Szmigiero wrote: > > > diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h > > > index 41efe53cf150..6fce6eb797a7 100644 > > > --- a/include/linux/kvm_host.h > > > +++ b/include/linux/kvm_host.h > > > @@ -848,6 +848,105 @@ struct kvm_memory_slot *id_to_memslot(struct kvm_memslots *slots, int id) > > > return NULL; > > > } > > > +/* Iterator used for walking memslots that overlap a gfn range. */ > > > +struct kvm_memslot_iter { > > > + struct kvm_memslots *slots; > > > + gfn_t end; > > > + struct rb_node *node; > > > +}; > > > > ... > > > > > +static inline struct kvm_memory_slot *kvm_memslot_iter_slot(struct kvm_memslot_iter *iter) > > > +{ > > > + return container_of(iter->node, struct kvm_memory_slot, gfn_node[iter->slots->node_idx]); > > > > Having to use a helper in callers of kvm_for_each_memslot_in_gfn_range() is a bit > > ugly, any reason not to grab @slot as well? Then the callers just do iter.slot, > > which IMO is much more readable. > > "slot" can be easily calculated from "node" together with either "slots" or > "node_idx" (the code above just adjusts a pointer) so storing it in the > iterator makes little sense if the later are already stored there. I don't want the callers to have to calculate the slot. It's mostly syntatic sugar, but I really do think it improves readability. And since the first thing every caller will do is retrieve the slot, I see no benefit in forcing the caller to do the work. E.g. in the simple kvm_check_memslot_overlap() usage, iter.slot->id is intuitive and easy to parse, whereas kvm_memslot_iter_slot(&iter)->id is slightly more difficult to parse and raises questions about why a function call is necessary and what the function might be doing. static bool kvm_check_memslot_overlap(struct kvm_memslots *slots, int id, gfn_t start, gfn_t end) { struct kvm_memslot_iter iter; kvm_for_each_memslot_in_gfn_range(&iter, slots, start, end) { if (iter.slot->id != id) return true; } return false; } vs. static bool kvm_check_memslot_overlap(struct kvm_memslots *slots, int id, gfn_t start, gfn_t end) { struct kvm_memslot_iter iter; kvm_for_each_memslot_in_gfn_range(&iter, slots, start, end) { if (kvm_memslot_iter_slot(&iter)->id != id) return true; } return false; }