Skip to content
  • Vamshi K Sthambamkadi's avatar
    Bluetooth: btusb: fix memory leak on suspend and resume · 5ff20cbe
    Vamshi K Sthambamkadi authored
    
    
    kmemleak report:
    unreferenced object 0xffff9b1127f00500 (size 208):
      comm "kworker/u17:2", pid 500, jiffies 4294937470 (age 580.136s)
      hex dump (first 32 bytes):
        00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
        00 60 ed 05 11 9b ff ff 00 00 00 00 00 00 00 00  .`..............
      backtrace:
        [<000000006ab3fd59>] kmem_cache_alloc_node+0x17a/0x480
        [<0000000051a5f6f9>] __alloc_skb+0x5b/0x1d0
        [<0000000037e2d252>] hci_prepare_cmd+0x32/0xc0 [bluetooth]
        [<0000000010b586d5>] hci_req_add_ev+0x84/0xe0 [bluetooth]
        [<00000000d2deb520>] hci_req_clear_event_filter+0x42/0x70 [bluetooth]
        [<00000000f864bd8c>] hci_req_prepare_suspend+0x84/0x470 [bluetooth]
        [<000000001deb2cc4>] hci_prepare_suspend+0x31/0x40 [bluetooth]
        [<000000002677dd79>] process_one_work+0x209/0x3b0
        [<00000000aaa62b07>] worker_thread+0x34/0x400
        [<00000000826d176c>] kthread+0x126/0x140
        [<000000002305e558>] ret_from_fork+0x22/0x30
    unreferenced object 0xffff9b1125c6ee00 (size 512):
      comm "kworker/u17:2", pid 500, jiffies 4294937470 (age 580.136s)
      hex dump (first 32 bytes):
        04 00 00 00 0d 00 00 00 05 0c 01 00 11 9b ff ff  ................
        00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00  ................
      backtrace:
        [<000000009f07c0cc>] slab_post_alloc_hook+0x59/0x270
        [<0000000049431dc2>] __kmalloc_node_track_caller+0x15f/0x330
        [<00000000027a42f6>] __kmalloc_reserve.isra.70+0x31/0x90
        [<00000000e8e3e76a>] __alloc_skb+0x87/0x1d0
        [<0000000037e2d252>] hci_prepare_cmd+0x32/0xc0 [bluetooth]
        [<0000000010b586d5>] hci_req_add_ev+0x84/0xe0 [bluetooth]
        [<00000000d2deb520>] hci_req_clear_event_filter+0x42/0x70 [bluetooth]
        [<00000000f864bd8c>] hci_req_prepare_suspend+0x84/0x470 [bluetooth]
        [<000000001deb2cc4>] hci_prepare_suspend+0x31/0x40 [bluetooth]
        [<000000002677dd79>] process_one_work+0x209/0x3b0
        [<00000000aaa62b07>] worker_thread+0x34/0x400
        [<00000000826d176c>] kthread+0x126/0x140
        [<000000002305e558>] ret_from_fork+0x22/0x30
    unreferenced object 0xffff9b112b395788 (size 8):
      comm "kworker/u17:2", pid 500, jiffies 4294937470 (age 580.136s)
      hex dump (first 8 bytes):
        20 00 00 00 00 00 04 00                           .......
      backtrace:
        [<0000000052dc28d2>] kmem_cache_alloc_trace+0x15e/0x460
        [<0000000046147591>] alloc_ctrl_urb+0x52/0xe0 [btusb]
        [<00000000a2ed3e9e>] btusb_send_frame+0x91/0x100 [btusb]
        [<000000001e66030e>] hci_send_frame+0x7e/0xf0 [bluetooth]
        [<00000000bf6b7269>] hci_cmd_work+0xc5/0x130 [bluetooth]
        [<000000002677dd79>] process_one_work+0x209/0x3b0
        [<00000000aaa62b07>] worker_thread+0x34/0x400
        [<00000000826d176c>] kthread+0x126/0x140
        [<000000002305e558>] ret_from_fork+0x22/0x30
    
    In pm sleep-resume context, while the btusb device rebinds, it enters
    hci_unregister_dev(), whilst there is a possibility of hdev receiving
    PM_POST_SUSPEND suspend_notifier event, leading to generation of msg
    frames. When hci_unregister_dev() completes, i.e. hdev context is
    destroyed/freed, those intermittently sent msg frames cause memory
    leak.
    
    BUG details:
    Below is stack trace of thread that enters hci_unregister_dev(), marks
    the hdev flag HCI_UNREGISTER to 1, and then goes onto to wait on notifier
    lock - refer unregister_pm_notifier().
    
      hci_unregister_dev+0xa5/0x320 [bluetoot]
      btusb_disconnect+0x68/0x150 [btusb]
      usb_unbind_interface+0x77/0x250
      ? kernfs_remove_by_name_ns+0x75/0xa0
      device_release_driver_internal+0xfe/0x1
      device_release_driver+0x12/0x20
      bus_remove_device+0xe1/0x150
      device_del+0x192/0x3e0
      ? usb_remove_ep_devs+0x1f/0x30
      usb_disable_device+0x92/0x1b0
      usb_disconnect+0xc2/0x270
      hub_event+0x9f6/0x15d0
      ? rpm_idle+0x23/0x360
      ? rpm_idle+0x26b/0x360
      process_one_work+0x209/0x3b0
      worker_thread+0x34/0x400
      ? process_one_work+0x3b0/0x3b0
      kthread+0x126/0x140
      ? kthread_park+0x90/0x90
      ret_from_fork+0x22/0x30
    
    Below is stack trace of thread executing hci_suspend_notifier() which
    processes the PM_POST_SUSPEND event, while the unbinding thread is
    waiting on lock.
    
      hci_suspend_notifier.cold.39+0x5/0x2b [bluetooth]
      blocking_notifier_call_chain+0x69/0x90
      pm_notifier_call_chain+0x1a/0x20
      pm_suspend.cold.9+0x334/0x352
      state_store+0x84/0xf0
      kobj_attr_store+0x12/0x20
      sysfs_kf_write+0x3b/0x40
      kernfs_fop_write+0xda/0x1c0
      vfs_write+0xbb/0x250
      ksys_write+0x61/0xe0
      __x64_sys_write+0x1a/0x20
      do_syscall_64+0x37/0x80
      entry_SYSCALL_64_after_hwframe+0x44/0xa9
    
    Fix hci_suspend_notifer(), not to act on events when flag HCI_UNREGISTER
    is set.
    
    Signed-off-by: default avatarVamshi K Sthambamkadi <vamshi.k.sthambamkadi@gmail.com>
    Signed-off-by: default avatarMarcel Holtmann <marcel@holtmann.org>
    5ff20cbe