• Yasuaki Ishimatsu's avatar
    mem hotunplug: fix kfree() of bootmem memory · ebff7d8f
    Yasuaki Ishimatsu authored
    When hot removing memory presented at boot time, following messages are shown:
    
      kernel BUG at mm/slub.c:3409!
      invalid opcode: 0000 [#1] SMP
      Modules linked in: ebtable_nat ebtables xt_CHECKSUM iptable_mangle bridge stp llc ipmi_devintf ipmi_msghandler sunrpc ipt_REJECT nf_conntrack_ipv4 nf_defrag_ipv4 iptable_filter ip_tables ip6t_REJECT nf_conntrack_ipv6 nf_defrag_ipv6 xt_state nf_conntrack ip6table_filter ip6_tables binfmt_misc vfat fat dm_mirror dm_region_hash dm_log dm_mod vhost_net macvtap macvlan tun uinput iTCO_wdt iTCO_vendor_support coretemp kvm_intel kvm crc32c_intel ghash_clmulni_intel microcode pcspkr sg i2c_i801 lpc_ich mfd_core igb i2c_algo_bit i2c_core e1000e ptp pps_core tpm_infineon ioatdma dca sr_mod cdrom sd_mod crc_t10dif usb_storage megaraid_sas lpfc scsi_transport_fc scsi_tgt scsi_mod
      CPU 0
      Pid: 5091, comm: kworker/0:2 Tainted: G        W    3.9.0-rc6+ #15
      RIP: kfree+0x232/0x240
      Process kworker/0:2 (pid: 5091, threadinfo ffff88084678c000, task ffff88083928ca80)
      Call Trace:
        __release_region+0xd4/0xe0
        __remove_pages+0x52/0x110
        arch_remove_memory+0x89/0xd0
        remove_memory+0xc4/0x100
        acpi_memory_device_remove+0x6d/0xb1
        acpi_device_remove+0x89/0xab
        __device_release_driver+0x7c/0xf0
        device_release_driver+0x2f/0x50
        acpi_bus_device_detach+0x6c/0x70
        acpi_ns_walk_namespace+0x11a/0x250
        acpi_walk_namespace+0xee/0x137
        acpi_bus_trim+0x33/0x7a
        acpi_bus_hot_remove_device+0xc4/0x1a1
        acpi_os_execute_deferred+0x27/0x34
        process_one_work+0x1f7/0x590
        worker_thread+0x11a/0x370
        kthread+0xee/0x100
        ret_from_fork+0x7c/0xb0
      RIP  [<ffffffff811c41d2>] kfree+0x232/0x240
       RSP <ffff88084678d968>
    
    The reason why the messages are shown is to release a resource
    structure, allocated by bootmem, by kfree().  So when we release a
    resource structure, we should check whether it is allocated by bootmem
    or not.
    
    But even if we know a resource structure is allocated by bootmem, we
    cannot release it since SLxB cannot treat it.  So for reusing a resource
    structure, this patch remembers it by using bootmem_resource as follows:
    
    When releasing a resource structure by free_resource(), free_resource()
    checks whether the resource structure is allocated by bootmem or not.
    If it is allocated by bootmem, free_resource() adds it to
    bootmem_resource.  If it is not allocated by bootmem, free_resource()
    release it by kfree().
    
    And when getting a new resource structure by get_resource(),
    get_resource() checks whether bootmem_resource has released resource
    structures or not.  If there is a released resource structure,
    get_resource() returns it.  If there is not a releaed resource
    structure, get_resource() returns new resource structure allocated by
    kzalloc().
    
    [akpm@linux-foundation.org: s/get_resource/alloc_resource/]
    Signed-off-by: 's avatarYasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
    Reviewed-by: 's avatarToshi Kani <toshi.kani@hp.com>
    Cc: Johannes Weiner <hannes@cmpxchg.org>
    Cc: Ram Pai <linuxram@us.ibm.com>
    Cc: David Rientjes <rientjes@google.com>
    Signed-off-by: 's avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: 's avatarLinus Torvalds <torvalds@linux-foundation.org>
    ebff7d8f
resource.c 31.7 KB