<feed xmlns='http://www.w3.org/2005/Atom'>
<title>linux-stable.git/drivers/base/firmware_class.c, branch v3.7.3</title>
<subtitle>Linux kernel stable tree</subtitle>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/'/>
<entry>
<title>firmware loader: Fix the concurrent request_firmware() race for kref_get/put</title>
<updated>2013-01-11T17:18:16+00:00</updated>
<author>
<name>Chuansheng Liu</name>
<email>chuansheng.liu@intel.com</email>
</author>
<published>2012-11-09T17:27:22+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=235db1e98f49a39427b87b491388cf645406e5fc'/>
<id>235db1e98f49a39427b87b491388cf645406e5fc</id>
<content type='text'>
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() --&gt;
_request_firmware_load() return err                   another request_firmware() is coming --&gt;
_request_firmware_cleanup is called --&gt;               _request_firmware_prepare --&gt;
release_firmware ---&gt;                                 fw_lookup_and_allocate_buf --&gt;
                                                      spin_lock(&amp;fwc-&gt;lock)
...                                                   __fw_lookup_buf() return true
fw_free_buf() will be called --&gt;                      ...
kref_put --&gt;
decrease the refcount to 0
                                                      kref_get(&amp;tmp-&gt;ref) ==&gt; it will trigger warning
                                                                              due to refcount == 0
__fw_free_buf() --&gt;
...                                                   spin_unlock(&amp;fwc-&gt;lock)
spin_lock(&amp;fwc-&gt;lock)
list_del(&amp;buf-&gt;list)
spin_unlock(&amp;fwc-&gt;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-&gt;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 &lt;ming.lei@canonical.com&gt;
Signed-off-by: liu chuansheng &lt;chuansheng.liu@intel.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;

</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
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() --&gt;
_request_firmware_load() return err                   another request_firmware() is coming --&gt;
_request_firmware_cleanup is called --&gt;               _request_firmware_prepare --&gt;
release_firmware ---&gt;                                 fw_lookup_and_allocate_buf --&gt;
                                                      spin_lock(&amp;fwc-&gt;lock)
...                                                   __fw_lookup_buf() return true
fw_free_buf() will be called --&gt;                      ...
kref_put --&gt;
decrease the refcount to 0
                                                      kref_get(&amp;tmp-&gt;ref) ==&gt; it will trigger warning
                                                                              due to refcount == 0
__fw_free_buf() --&gt;
...                                                   spin_unlock(&amp;fwc-&gt;lock)
spin_lock(&amp;fwc-&gt;lock)
list_del(&amp;buf-&gt;list)
spin_unlock(&amp;fwc-&gt;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-&gt;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 &lt;ming.lei@canonical.com&gt;
Signed-off-by: liu chuansheng &lt;chuansheng.liu@intel.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;

</pre>
</div>
</content>
</entry>
<entry>
<title>firmware loader: Fix the race FW_STATUS_DONE is followed by class_timeout</title>
<updated>2013-01-11T17:18:16+00:00</updated>
<author>
<name>Chuansheng Liu</name>
<email>chuansheng.liu@intel.com</email>
</author>
<published>2012-11-08T11:14:40+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=42b5489a2b5163c01e2fe23a609d397facfd0509'/>
<id>42b5489a2b5163c01e2fe23a609d397facfd0509</id>
<content type='text'>
commit ce2fcbd99cef580623116bb33531dbc3e6f690b0 upstream.

There is a race as below when calling request_firmware():
CPU1                                   CPU2
write 0 &gt; loading
mutex_lock(&amp;fw_lock)
...
set_bit FW_STATUS_DONE                 class_timeout is coming
                                       set_bit FW_STATUS_ABORT
complete_all &amp;completion
...
mutex_unlock(&amp;fw_lock)

In this time, the bit FW_STATUS_DONE and FW_STATUS_ABORT are set,
and request_firmware() will return failure due to condition in
_request_firmware_load():
	if (!buf-&gt;size || test_bit(FW_STATUS_ABORT, &amp;buf-&gt;status))
		retval = -ENOENT;

But from the above scenerio, it should be a successful requesting.
So we need judge if the bit FW_STATUS_DONE is already set before
calling fw_load_abort() in timeout function.

As Ming's proposal, we need change the timer into sched_work to
benefit from using &amp;fw_lock mutex also.

Signed-off-by: liu chuansheng &lt;chuansheng.liu@intel.com&gt;
Acked-by: Ming Lei &lt;ming.lei@canonical.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;

</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
commit ce2fcbd99cef580623116bb33531dbc3e6f690b0 upstream.

There is a race as below when calling request_firmware():
CPU1                                   CPU2
write 0 &gt; loading
mutex_lock(&amp;fw_lock)
...
set_bit FW_STATUS_DONE                 class_timeout is coming
                                       set_bit FW_STATUS_ABORT
complete_all &amp;completion
...
mutex_unlock(&amp;fw_lock)

In this time, the bit FW_STATUS_DONE and FW_STATUS_ABORT are set,
and request_firmware() will return failure due to condition in
_request_firmware_load():
	if (!buf-&gt;size || test_bit(FW_STATUS_ABORT, &amp;buf-&gt;status))
		retval = -ENOENT;

But from the above scenerio, it should be a successful requesting.
So we need judge if the bit FW_STATUS_DONE is already set before
calling fw_load_abort() in timeout function.

As Ming's proposal, we need change the timer into sched_work to
benefit from using &amp;fw_lock mutex also.

Signed-off-by: liu chuansheng &lt;chuansheng.liu@intel.com&gt;
Acked-by: Ming Lei &lt;ming.lei@canonical.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;

</pre>
</div>
</content>
</entry>
<entry>
<title>firmware loader: sync firmware cache by async_synchronize_full_domain</title>
<updated>2012-10-22T15:37:18+00:00</updated>
<author>
<name>Ming Lei</name>
<email>ming.lei@canonical.com</email>
</author>
<published>2012-10-09T04:01:04+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=d28d3882bd1fdb88ae4e02f11b091a92b0e5068b'/>
<id>d28d3882bd1fdb88ae4e02f11b091a92b0e5068b</id>
<content type='text'>
async.c has provided synchronization mechanism on async_schedule_*,
so use async_synchronize_full_domain to sync caching firmware instead
of reinventing the wheel.

Signed-off-by: Ming Lei &lt;ming.lei@canonical.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
async.c has provided synchronization mechanism on async_schedule_*,
so use async_synchronize_full_domain to sync caching firmware instead
of reinventing the wheel.

Signed-off-by: Ming Lei &lt;ming.lei@canonical.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>firmware loader: let direct loading back on 'firmware_buf'</title>
<updated>2012-10-22T15:37:17+00:00</updated>
<author>
<name>Ming Lei</name>
<email>ming.lei@canonical.com</email>
</author>
<published>2012-10-09T04:01:03+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=746058f4304343507e48d39f80d7a3b0d8550e3a'/>
<id>746058f4304343507e48d39f80d7a3b0d8550e3a</id>
<content type='text'>
Firstly 'firmware_buf' is introduced to make all loading requests
to share one firmware kernel buffer, so firmware_buf should
be used in direct loading for saving memory and speedup firmware
loading.

Secondly, the commit below

	abb139e75c2cdbb955e840d6331cb5863e409d0e(firmware:teach
	the kernel to load firmware files directly from the filesystem)

introduces direct loading for fixing udev regression, but it
bypasses the firmware cache meachnism, so this patch enables
caching firmware for direct loading case since it is still needed
to solve drivers' dependency during system resume.

Cc: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
Signed-off-by: Ming Lei &lt;ming.lei@canonical.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Firstly 'firmware_buf' is introduced to make all loading requests
to share one firmware kernel buffer, so firmware_buf should
be used in direct loading for saving memory and speedup firmware
loading.

Secondly, the commit below

	abb139e75c2cdbb955e840d6331cb5863e409d0e(firmware:teach
	the kernel to load firmware files directly from the filesystem)

introduces direct loading for fixing udev regression, but it
bypasses the firmware cache meachnism, so this patch enables
caching firmware for direct loading case since it is still needed
to solve drivers' dependency during system resume.

Cc: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
Signed-off-by: Ming Lei &lt;ming.lei@canonical.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>firmware loader: fix one reqeust_firmware race</title>
<updated>2012-10-22T15:37:17+00:00</updated>
<author>
<name>Ming Lei</name>
<email>ming.lei@canonical.com</email>
</author>
<published>2012-10-09T04:01:02+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=253c9240ee09fd2a05d315ea44ac037a893d8981'/>
<id>253c9240ee09fd2a05d315ea44ac037a893d8981</id>
<content type='text'>
Several loading requests may be pending on one same
firmware buf, and this patch moves fw_map_pages_buf()
before complete_all(&amp;fw_buf-&gt;completion) and let all
requests see the mapped 'buf-&gt;data' once the loading
is completed.

Signed-off-by: Ming Lei &lt;ming.lei@canonical.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Several loading requests may be pending on one same
firmware buf, and this patch moves fw_map_pages_buf()
before complete_all(&amp;fw_buf-&gt;completion) and let all
requests see the mapped 'buf-&gt;data' once the loading
is completed.

Signed-off-by: Ming Lei &lt;ming.lei@canonical.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>firmware loader: cancel uncache work before caching firmware</title>
<updated>2012-10-22T15:37:16+00:00</updated>
<author>
<name>Ming Lei</name>
<email>ming.lei@canonical.com</email>
</author>
<published>2012-10-09T04:01:01+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=373304fe10fc46e68815c7116709ad292695dfd1'/>
<id>373304fe10fc46e68815c7116709ad292695dfd1</id>
<content type='text'>
Under 'Opportunistic sleep' situation, system sleep might be
triggered very frequently, so the uncahce work may not be completed
before caching firmware during next suspend.

This patch cancels the uncache work before caching firmware to
fix the problem above.

Also this patch optimizes the cacheing firmware mechanism a bit by
only storing one firmware cache entry for one firmware image.

So if the firmware is still cached during suspend, it doesn't need
to be loaded from user space any more.

Signed-off-by: Ming Lei &lt;ming.lei@canonical.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Under 'Opportunistic sleep' situation, system sleep might be
triggered very frequently, so the uncahce work may not be completed
before caching firmware during next suspend.

This patch cancels the uncache work before caching firmware to
fix the problem above.

Also this patch optimizes the cacheing firmware mechanism a bit by
only storing one firmware cache entry for one firmware image.

So if the firmware is still cached during suspend, it doesn't need
to be loaded from user space any more.

Signed-off-by: Ming Lei &lt;ming.lei@canonical.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>firmware: use 'kernel_read()' to read firmware into kernel buffer</title>
<updated>2012-10-04T16:19:02+00:00</updated>
<author>
<name>Linus Torvalds</name>
<email>torvalds@linux-foundation.org</email>
</author>
<published>2012-10-04T16:19:02+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=ce57e981f2b996aaca2031003b3f866368307766'/>
<id>ce57e981f2b996aaca2031003b3f866368307766</id>
<content type='text'>
Fengguang correctly points out that the firmware reading should not use
vfs_read(), since the buffer is in kernel space.

The vfs_read() just happened to work for kernel threads, but sparse
warns about the incorrect address spaces, and it's definitely incorrect
and could fail for other users of the firmware loading.

Reported-by: Fengguang Wu &lt;fengguang.wu@intel.com&gt;
Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Fengguang correctly points out that the firmware reading should not use
vfs_read(), since the buffer is in kernel space.

The vfs_read() just happened to work for kernel threads, but sparse
warns about the incorrect address spaces, and it's definitely incorrect
and could fail for other users of the firmware loading.

Reported-by: Fengguang Wu &lt;fengguang.wu@intel.com&gt;
Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>firmware: teach the kernel to load firmware files directly from the filesystem</title>
<updated>2012-10-03T22:58:32+00:00</updated>
<author>
<name>Linus Torvalds</name>
<email>torvalds@linux-foundation.org</email>
</author>
<published>2012-10-03T22:58:32+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=abb139e75c2cdbb955e840d6331cb5863e409d0e'/>
<id>abb139e75c2cdbb955e840d6331cb5863e409d0e</id>
<content type='text'>
This is a first step in allowing people to by-pass udev for loading
device firmware.  Current versions of udev will deadlock (causing us to
block for the 30 second timeout) under some circumstances if the
firmware is loaded as part of the module initialization path, and this
is causing problems for media drivers in particular.

The current patch hardcodes the firmware path that udev uses by default,
and will fall back to the legacy udev mode if the firmware cannot be
found there.  We'd like to add support for both configuring the paths
and the fallback behaviour, but in the meantime this hopefully fixes the
immediate problem, while also giving us a way forward.

[ v2: Some VFS layer interface cleanups suggested by Al Viro ]
[ v3: use the default udev paths suggested by Kay Sievers ]

Suggested-by: Ivan Kalvachev &lt;ikalvachev@gmail.com&gt;
Acked-by: Greg KH &lt;gregkh@linuxfoundation.org&gt;
Acked-by: Al Viro &lt;viro@zeniv.linux.org.uk&gt;
Cc: Mauro Carvalho Chehab &lt;mchehab@redhat.com&gt;
Cc: Kay Sievers &lt;kay@redhat.com&gt;
Cc: Ming Lei &lt;ming.lei@canonical.com&gt;
Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This is a first step in allowing people to by-pass udev for loading
device firmware.  Current versions of udev will deadlock (causing us to
block for the 30 second timeout) under some circumstances if the
firmware is loaded as part of the module initialization path, and this
is causing problems for media drivers in particular.

The current patch hardcodes the firmware path that udev uses by default,
and will fall back to the legacy udev mode if the firmware cannot be
found there.  We'd like to add support for both configuring the paths
and the fallback behaviour, but in the meantime this hopefully fixes the
immediate problem, while also giving us a way forward.

[ v2: Some VFS layer interface cleanups suggested by Al Viro ]
[ v3: use the default udev paths suggested by Kay Sievers ]

Suggested-by: Ivan Kalvachev &lt;ikalvachev@gmail.com&gt;
Acked-by: Greg KH &lt;gregkh@linuxfoundation.org&gt;
Acked-by: Al Viro &lt;viro@zeniv.linux.org.uk&gt;
Cc: Mauro Carvalho Chehab &lt;mchehab@redhat.com&gt;
Cc: Kay Sievers &lt;kay@redhat.com&gt;
Cc: Ming Lei &lt;ming.lei@canonical.com&gt;
Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>firmware loader: fix compile warning when CONFIG_PM=n</title>
<updated>2012-09-10T23:40:30+00:00</updated>
<author>
<name>Ming Lei</name>
<email>ming.lei@canonical.com</email>
</author>
<published>2012-09-08T09:32:30+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=cfe016b14e1ee106e906ddfe77d598a2b288d7d6'/>
<id>cfe016b14e1ee106e906ddfe77d598a2b288d7d6</id>
<content type='text'>
This patch replaces the previous macro of CONFIG_PM with
CONFIG_PM_SLEEP becasue firmware cache is only used in
system sleep situations.

Also this patch fixes the below compile warning when
CONFIG_PM=n:

	drivers/base/firmware_class.c:1147: warning: 'device_cache_fw_images'
	defined but not used
	drivers/base/firmware_class.c:1212: warning:
	'device_uncache_fw_images_delay' defined but not used

Reported-by: Andrew Morton &lt;akpm@linux-foundation.org&gt;
Signed-off-by: Ming Lei &lt;ming.lei@canonical.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This patch replaces the previous macro of CONFIG_PM with
CONFIG_PM_SLEEP becasue firmware cache is only used in
system sleep situations.

Also this patch fixes the below compile warning when
CONFIG_PM=n:

	drivers/base/firmware_class.c:1147: warning: 'device_cache_fw_images'
	defined but not used
	drivers/base/firmware_class.c:1212: warning:
	'device_uncache_fw_images_delay' defined but not used

Reported-by: Andrew Morton &lt;akpm@linux-foundation.org&gt;
Signed-off-by: Ming Lei &lt;ming.lei@canonical.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>firmware loader: let caching firmware piggyback on loading firmware</title>
<updated>2012-09-06T21:46:16+00:00</updated>
<author>
<name>Ming Lei</name>
<email>ming.lei@canonical.com</email>
</author>
<published>2012-08-20T11:04:16+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=ac39b3ea73aacde876d1d5ee1ca3e2719f771482'/>
<id>ac39b3ea73aacde876d1d5ee1ca3e2719f771482</id>
<content type='text'>
After starting caching firmware, there is still some time left
before devices are suspended, during the period, request_firmware
or its nowait version may still be triggered by the below situations
to load firmware images which can't be cached during suspend/resume
cycle.

	- new devices added
	- driver bind
	- or device open kind of things

This patch utilizes the piggyback trick to cache firmware for
this kind of situation: just increase the firmware buf's reference
count and add the fw name entry into cache entry list after starting
caching firmware and before syscore_suspend() is called.

Signed-off-by: Ming Lei &lt;ming.lei@canonical.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
After starting caching firmware, there is still some time left
before devices are suspended, during the period, request_firmware
or its nowait version may still be triggered by the below situations
to load firmware images which can't be cached during suspend/resume
cycle.

	- new devices added
	- driver bind
	- or device open kind of things

This patch utilizes the piggyback trick to cache firmware for
this kind of situation: just increase the firmware buf's reference
count and add the fw name entry into cache entry list after starting
caching firmware and before syscore_suspend() is called.

Signed-off-by: Ming Lei &lt;ming.lei@canonical.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</pre>
</div>
</content>
</entry>
</feed>
