• Konrad Rzeszutek Wilk's avatar
    xen/smp: Fix CPU online/offline bug triggering a BUG: scheduling while atomic. · 41bd956d
    Konrad Rzeszutek Wilk authored
    When a user offlines a VCPU and then onlines it, we get:
    
    NMI watchdog disabled (cpu2): hardware events not enabled
    BUG: scheduling while atomic: swapper/2/0/0x00000002
    Modules linked in: dm_multipath dm_mod xen_evtchn iscsi_boot_sysfs iscsi_tcp libiscsi_tcp libiscsi scsi_transport_iscsi scsi_mod libcrc32c crc32c radeon fbco
     ttm bitblit softcursor drm_kms_helper xen_blkfront xen_netfront xen_fbfront fb_sys_fops sysimgblt sysfillrect syscopyarea xen_kbdfront xenfs [last unloaded:
    
    Pid: 0, comm: swapper/2 Tainted: G           O 3.2.0phase15.1-00003-gd6f7f5b-dirty #4
    Call Trace:
     [<ffffffff81070571>] __schedule_bug+0x61/0x70
     [<ffffffff8158eb78>] __schedule+0x798/0x850
     [<ffffffff8158ed6a>] schedule+0x3a/0x50
     [<ffffffff810349be>] cpu_idle+0xbe/0xe0
     [<ffffffff81583599>] cpu_bringup_and_idle+0xe/0x10
    
    The reason for this should be obvious from this call-chain:
    cpu_bringup_and_idle:
     \- cpu_bringup
      |   \-[preempt_disable]
      |
      |- cpu_idle
           \- play_dead [assuming the user offlined the VCPU]
           |     \
           |     +- (xen_play_dead)
           |          \- HYPERVISOR_VCPU_off [so VCPU is dead, once user
           |          |                       onlines it starts from here]
           |          \- cpu_bringup [preempt_disable]
           |
           +- preempt_enable_no_reschedule()
           +- schedule()
           \- preempt_enable()
    
    So we have two preempt_disble() and one preempt_enable(). Calling
    preempt_enable() after the cpu_bringup() in the xen_play_dead
    fixes the imbalance.
    Signed-off-by: default avatarKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>
    41bd956d
smp.c 13.2 KB