printk_persist: Add cache flushing

printk_persist tries to persist the printk buffer across reboots.
Experiments showed that data stored in DRAM is preserved across reboots,
but anything in any of the L1 caches or the L2 cache is lost. Without
cache flushing, we end with inconsistent data on reboot. In many cases,
we found entire cache lines being stale. The printk buffer data
structure is especially sensitive to an outdated log_first_idx pointer.

We looked into multiple approaches including a recovery procedure that
can tolerate stale and inconsistent meta data. We ultimately settled for
an approach where we keep the DRAM in sync. In other words, we flush the
L1/L2 caches after every printk() very similar to dma_map_single(). As
an optimization, we moved all the critical meta data into one cache line
namely _log_first_seq, _log_first_idx, _log_next_seq and _log_next_idx.

We developed a test case that failed on every single iteration with the
current printk_persist implementation. This change dramatically reduces
the failure rate to 0.2% (3 failures during 1450 iterations).

Change-Id: Ie01e9b5cca2450f7bb4df094036631e6804f5f61
1 file changed