Skip to content
  • Greg Thelen's avatar
    writeback: safer lock nesting · 2e898e4c
    Greg Thelen authored
    lock_page_memcg()/unlock_page_memcg() use spin_lock_irqsave/restore() if
    the page's memcg is undergoing move accounting, which occurs when a
    process leaves its memcg for a new one that has
    memory.move_charge_at_immigrate set.
    
    unlocked_inode_to_wb_begin,end() use spin_lock_irq/spin_unlock_irq() if
    the given inode is switching writeback domains.  Switches occur when
    enough writes are issued from a new domain.
    
    This existing pattern is thus suspicious:
        lock_page_memcg(page);
        unlocked_inode_to_wb_begin(inode, &locked);
        ...
        unlocked_inode_to_wb_end(inode, locked);
        unlock_page_memcg(page);
    
    If both inode switch and process memcg migration are both in-flight then
    unlocked_inode_to_wb_end() will unconditionally enable interrupts while
    still holding the lock_page_memcg() irq spinlock.  This suggests the
    possibility of deadlock if an interrupt occurs before unlock_page_memcg().
    
        truncate
        __cancel_dirty_page
        lock_page_memcg
        unlocked_inode_to_wb_begin...
    2e898e4c