I've now gone through reverse bisecting between mainline stable kernels
3.7.1 and 3.7.2, and the commit that seems to solve this issue is:

235db1e98f49a39427b87b491388cf645406e5fc is the first bad commit
commit 235db1e98f49a39427b87b491388cf645406e5fc
Author: Chuansheng Liu <chuansheng....@intel.com>
Date: Sat Nov 10 01:27:22 2012 +0800

firmware loader: Fix the concurrent request_firmware() race for
kref_get/put

commit bd9eb7fbe69111ea0ff1f999ef4a5f26d223d1d5 upstream.

There is one race that both request_firmware() with the same
firmware name.

The race scenerio is as below:
CPU1 CPU2
request_firmware() -->
_request_firmware_load() return err another request_firmware() is coming -->
_request_firmware_cleanup is called --> _request_firmware_prepare -->
release_firmware ---> fw_lookup_and_allocate_buf -->
spin_lock(&fwc->lock)
... __fw_lookup_buf() return true
fw_free_buf() will be called --> ...
kref_put -->
decrease the refcount to 0
kref_get(&tmp->ref) ==> it will trigger warning
due to refcount == 0
__fw_free_buf() -->
... spin_unlock(&fwc->lock)
spin_lock(&fwc->lock)
list_del(&buf->list)
spin_unlock(&fwc->lock)
kfree(buf)
After that, the freed buf will be used.

The key race is decreasing refcount to 0 and list_del is not protected together 
by
fwc->lock, and it is possible another thread try to get it between refcount==0
and list_del.

Fix it here to protect it together.

Acked-by: Ming Lei <ming....@canonical.com>
Signed-off-by: liu chuansheng <chuansheng....@intel.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>

-- 
You received this bug notification because you are a member of Ubuntu
Bugs, which is subscribed to Ubuntu.
https://bugs.launchpad.net/bugs/1067548

Title:
  Restarting hangs

To manage notifications about this bug go to:
https://bugs.launchpad.net/linux/+bug/1067548/+subscriptions

-- 
ubuntu-bugs mailing list
ubuntu-bugs@lists.ubuntu.com
https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs

Reply via email to