memory: optimize memory_region_sync_dirty_bitmap
Avoid walking the FlatView of all address spaces. Most of the address spaces will have no log_sync callback on their listeners. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
		
							parent
							
								
									adaad61c3c
								
							
						
					
					
						commit
						0a752eeea8
					
				
							
								
								
									
										18
									
								
								memory.c
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								memory.c
									
									
									
									
									
								
							@ -1642,14 +1642,26 @@ bool memory_region_test_and_clear_dirty(MemoryRegion *mr, hwaddr addr,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void memory_region_sync_dirty_bitmap(MemoryRegion *mr)
 | 
					void memory_region_sync_dirty_bitmap(MemoryRegion *mr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    MemoryListener *listener;
 | 
				
			||||||
    AddressSpace *as;
 | 
					    AddressSpace *as;
 | 
				
			||||||
 | 
					    FlatView *view;
 | 
				
			||||||
    FlatRange *fr;
 | 
					    FlatRange *fr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    QTAILQ_FOREACH(as, &address_spaces, address_spaces_link) {
 | 
					    /* If the same address space has multiple log_sync listeners, we
 | 
				
			||||||
        FlatView *view = address_space_get_flatview(as);
 | 
					     * visit that address space's FlatView multiple times.  But because
 | 
				
			||||||
 | 
					     * log_sync listeners are rare, it's still cheaper than walking each
 | 
				
			||||||
 | 
					     * address space once.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    QTAILQ_FOREACH(listener, &memory_listeners, link) {
 | 
				
			||||||
 | 
					        if (!listener->log_sync) {
 | 
				
			||||||
 | 
					            continue;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        as = listener->address_space;
 | 
				
			||||||
 | 
					        view = address_space_get_flatview(as);
 | 
				
			||||||
        FOR_EACH_FLAT_RANGE(fr, view) {
 | 
					        FOR_EACH_FLAT_RANGE(fr, view) {
 | 
				
			||||||
            if (fr->mr == mr) {
 | 
					            if (fr->mr == mr) {
 | 
				
			||||||
                MEMORY_LISTENER_UPDATE_REGION(fr, as, Forward, log_sync);
 | 
					                MemoryRegionSection mrs = section_from_flat_range(fr, as);
 | 
				
			||||||
 | 
					                listener->log_sync(listener, &mrs);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        flatview_unref(view);
 | 
					        flatview_unref(view);
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user