Hi -
Yesterday I studied suspend status on 3.0 kernel for Panda, for mem
suspend it's working pretty well in Ubuntu case, desktop is coming back
up woken by USB keyboard action, WLAN is workable after reassociation.
However in Android case, the same tree merged with common-android-3.0 to
get Androidization is blowing chunks in suspend / resume, entering a
loop where it aborts suspend and then tries to suspend again all the time.
Increasing the debug level in wakelock code shows at least two guys that
can make trouble, locks "mmc_delayed_work" and "alarm_rtc".
"mmc_delayed_work" casues wakelock stuff to return -EAGAIN, and
"alarm_rtc" seems to timeout as a wakelock, but leave the alarm device
in a state where it will abort suspend on -EBUSY.
I took a look in drivers/mmc/core/core.c to see what the wakelock
support patches had done there and was a bit surprised.
They have a single wakelock to cover delayed work in there, however
there are multiple delayed works possible to be queued, eg delayed
disable and delayed detect actions, and although they wrap scheduling
the delayed work to also lock the wakelock, they don't wrap cancelling
it, eg -->
void mmc_stop_host(struct mmc_host *host)
{
...
if (host->caps & MMC_CAP_DISABLE)
cancel_delayed_work(&host->disable);
cancel_delayed_work_sync(&host->detect);
mmc_flush_scheduled_work();
Nor do wakelocks seem to maintain counters, they're either locked or
unlocked.
So the following code looks highly suspicious:
static int mmc_schedule_delayed_work(struct delayed_work *work,
unsigned long delay)
{
wake_lock(&mmc_delayed_work_wake_lock);
return queue_delayed_work(workqueue, work, delay);
}
static int mmc_host_do_disable(struct mmc_host *host, int lazy)
{
....
(conditionally)
mmc_schedule_delayed_work(&host->disable, delay);
...
}
void mmc_host_deeper_disable(struct work_struct *work)
{
...
mmc_host_do_disable(host, 1);
...
wake_unlock(&mmc_delayed_work_wake_lock);
}
Ie mmc_host_deeper_disable() can provoke delayed work which it proceeds
to unlock wakelock coverage for.
To the point of the symptoms:
int mmc_pm_notify(struct notifier_block *notify_block,
unsigned long mode, void *unused)
{
...
switch (mode) {
case PM_HIBERNATION_PREPARE:
case PM_SUSPEND_PREPARE:
...
cancel_delayed_work_sync(&host->detect);
So here when preparing for suspend we can cancel the delayed work we
presumably arranged wakelock coverage for, without unlocking the wakelock.
Am I missing the point or is some work needed to improve wakelock
application for mmc stuff in common-android-3.0?
-Andy
--
Andy Green | TI Landing Team Leader
Linaro.org │ Open source software for ARM SoCs | Follow Linaro
http://facebook.com/pages/Linaro/155974581091106 -
http://twitter.com/#!/linaroorg - http://linaro.org/linaro-blog
All,
We need your help. Over the weekend we "upgraded" our building of
natty based images from using live-helper 2 to live-build 3. (same
tool just slightly newer name and more shiny) It is possible that
given evolutionary changes to the build tool that there maybe new and
interesting bugs introduced.
11.07 isn't that far away so time spent testing NOW will mean less
late night debug sessions later.
Here's what you need to do.
>From snapshots.linaro.org download a the July 6th build: one of alip,
developer, nano or ubuntu-desktop and a hwpack for your board. Use
linaro-media-create to get the image onto an SD. Boot said combination
on your board and report the results on qatracker.linaro.org.
Please take some time to DO THIS TODAY. The earlier we find
regressions in what will be 11.07 the better.
If you're able to test more than one image/hwpack combination, that's
all the more awesome, with awesome sauce!
Thanks!
--
Regards,
Tom
"We want great men who, when fortune frowns will not be discouraged."
- Colonel Henry Knox
Linaro.org │ Open source software for ARM SoCs
w) tom.gall att linaro.org
w) tom_gall att vnet.ibm.com
h) tom_gall att mac.com
Hi
Linaro backport PPA [1] got updated to latest versions of armel cross
toolchains -- oneiric packages were used as a base.
What got changed:
- gcc 4.4 was updated to 4.4.6-3ubuntu1
- gcc 4.5 was updated to 4.5.3-1ubuntu2
- binutils was updated to 2.21.52.20110606-1ubuntu1
- eglibc was updated to 2.13-6ubuntu2
- gcc 4.6 was provided as 4.6.0-14ubuntu1 in Maverick, Natty
- gcc-defaults-armel-cross was updated to 1.6 in Maverick, Natty (uses
gcc-4.6 as default)
There is no gcc-4.6 for Lucid currently as it requires newer versions of
few libraries (mpfr, mpc) and one of rule of this PPA is "do not update
packages which may affect other packages".
Please test them and report any bugs found.
1. https://launchpad.net/~linaro-maintainers/+archive/toolchain/
== Frans Gifford <fgiff> ==
=== Highlights ===
* Established weekly hacking sessions with LT.
* Started working with LT to get Linaro android working with STE
u-boot and kernel.
* Continued discussions about connecting android-build.l.o and
validation.l.o and sent first build script changes for review.
=== Plans ===
* Finalise android-build script.
* Work with LT to get android working on Snowball.
=== Issues ===
* Need to get mumble working properly.
* Need to source a MiniUSB-A to USB-A adapter so I can connect USB
hub and then keyboard to Snowball.
--
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
Documentation about the background and the design of mmc non-blocking.
Host driver guidelines to minimize request preparation overhead.
Signed-off-by: Per Forlin <per.forlin(a)linaro.org>
---
ChangeLog:
v2: - Minor updates after proofreading comments from Chris
v3: - Minor updates after more comments from Chris
v4: - Minor updates after comments from Randy
Documentation/mmc/00-INDEX | 2 +
Documentation/mmc/mmc-async-req.txt | 86 +++++++++++++++++++++++++++++++++++
2 files changed, 88 insertions(+), 0 deletions(-)
create mode 100644 Documentation/mmc/mmc-async-req.txt
diff --git a/Documentation/mmc/00-INDEX b/Documentation/mmc/00-INDEX
index 93dd7a7..a9ba672 100644
--- a/Documentation/mmc/00-INDEX
+++ b/Documentation/mmc/00-INDEX
@@ -4,3 +4,5 @@ mmc-dev-attrs.txt
- info on SD and MMC device attributes
mmc-dev-parts.txt
- info on SD and MMC device partitions
+mmc-async-req.txt
+ - info on mmc asynchronous requests
diff --git a/Documentation/mmc/mmc-async-req.txt b/Documentation/mmc/mmc-async-req.txt
new file mode 100644
index 0000000..4877f29
--- /dev/null
+++ b/Documentation/mmc/mmc-async-req.txt
@@ -0,0 +1,86 @@
+Rationale
+=========
+
+How significant is the cache maintenance overhead?
+It depends. Fast eMMC and multiple cache levels with speculative cache
+pre-fetch makes the cache overhead relatively significant. If the DMA
+preparations for the next request are done in parallel with the current
+transfer, the DMA preparation overhead would not affect the MMC performance.
+The intention of non-blocking (asynchronous) MMC requests is to minimize the
+time between when an MMC request ends and another MMC request begins.
+Using mmc_wait_for_req(), the MMC controller is idle while dma_map_sg and
+dma_unmap_sg are processing. Using non-blocking MMC requests makes it
+possible to prepare the caches for next job in parallel with an active
+MMC request.
+
+MMC block driver
+================
+
+The issue_rw_rq() in the MMC block driver is made non-blocking.
+The increase in throughput is proportional to the time it takes to
+prepare (major part of preparations are dma_map_sg and dma_unmap_sg)
+a request and how fast the memory is. The faster the MMC/SD is
+the more significant the prepare request time becomes. Roughly the expected
+performance gain is 5% for large writes and 10% on large reads on a L2 cache
+platform. In power save mode, when clocks run on a lower frequency, the DMA
+preparation may cost even more. As long as these slower preparations are run
+in parallel with the transfer performance wont be affected.
+
+Details on measurements from IOZone and mmc_test
+================================================
+
+https://wiki.linaro.org/WorkingGroups/Kernel/Specs/StoragePerfMMC-async-req
+
+MMC core API extension
+======================
+
+There is one new public function mmc_start_req().
+It starts a new MMC command request for a host. The function isn't
+truly non-blocking. If there is on ongoing async request it waits
+for completion of that request and starts the new one and returns. It
+doesn't wait for the new request to complete. If there is no ongoing
+request it starts the new request and returns immediately.
+
+MMC host extensions
+===================
+
+There are two optional hooks -- pre_req() and post_req() -- that the host
+driver may implement in order to move work to before and after the actual
+mmc_request function is called. In the DMA case pre_req() may do
+dma_map_sg() and prepare the DMA descriptor, and post_req runs
+the dma_unmap_sg.
+
+Optimize for the first request
+==============================
+
+The first request in a series of requests can't be prepared in parallel with
+the previous transfer, since there is no previous request.
+The argument is_first_req in pre_req() indicates that there is no previous
+request. The host driver may optimize for this scenario to minimize
+the performance loss. A way to optimize for this is to split the current
+request in two chunks, prepare the first chunk and start the request,
+and finally prepare the second chunk and start the transfer.
+
+Pseudocode to handle is_first_req scenario with minimal prepare overhead:
+if (is_first_req && req->size > threshold)
+ /* start MMC transfer for the complete transfer size */
+ mmc_start_command(MMC_CMD_TRANSFER_FULL_SIZE);
+
+ /*
+ * Begin to prepare DMA while cmd is being processed by MMC.
+ * The first chunk of the request should take the same time
+ * to prepare as the "MMC process command time".
+ * If prepare time exceeds MMC cmd time
+ * the transfer is delayed, guesstimate max 4k as first chunk size.
+ */
+ prepare_1st_chunk_for_dma(req);
+ /* flush pending desc to the DMAC (dmaengine.h) */
+ dma_issue_pending(req->dma_desc);
+
+ prepare_2nd_chunk_for_dma(req);
+ /*
+ * The second issue_pending should be called before MMC runs out
+ * of the first chunk. If the MMC runs out of the first data chunk
+ * before this call, the transfer is delayed.
+ */
+ dma_issue_pending(req->dma_desc);
--
1.7.4.1
changes since v2:
* Minor updates after more comments from Chris
Per Forlin (1):
mmc: documentation of mmc non-blocking request usage and design.
Documentation/mmc/00-INDEX | 2 +
Documentation/mmc/mmc-async-req.txt | 86 +++++++++++++++++++++++++++++++++++
2 files changed, 88 insertions(+), 0 deletions(-)
create mode 100644 Documentation/mmc/mmc-async-req.txt
--
1.7.4.1