diff options
author | Kevin Hilman <khilman@linaro.org> | 2014-12-15 13:59:43 -0800 |
---|---|---|
committer | Kevin Hilman <khilman@linaro.org> | 2014-12-15 13:59:43 -0800 |
commit | 1888d2fa314033755026ceddee1fff8f80659fe4 (patch) | |
tree | b0085323f5db6dca5f259b92038e27843c5a43a6 /drivers/md/persistent-data/dm-transaction-manager.c | |
parent | 9d312cd12e89ce08add99fe66e8f6baeaca16d7d (diff) | |
parent | 661ea91b676bcca137c1c3fe838997925ce98060 (diff) |
Merge tag 'omap-for-v3.19/fixes-for-merge-window' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap into fixes
From: Tony Lindgren <tony@atomide.com>
Subject: [GIT PULL] few fixes for the v3.19 merge window
Fixes for a few issues found that would be good to get
into -rc1:
- Update SoC revision detection for am43x es1.2
- Fix regression with GPMC timings on 2430sdp for some versions
of u-boot
- Fix dra7 watchdog compatible property
- Fix am437x-sk-evm LCD timings
- Fix dra7 DSS clock muxing
- Fix dra7-evm voltages
- Remove a unused function prototype for am33xx_clk_init
- Enable AHCI in the omap2plus_defconfig
* tag 'omap-for-v3.19/fixes-for-merge-window' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap: (1601 commits)
ARM: omap2plus_defconfig: Enable AHCI_PLATFORM driver
ARM: dts: am437x-sk-evm.dts: fix LCD timings
ARM: dts: dra7-evm: Update SMPS7 (VDD_CORE) max voltage to match DM
ARM: dts: dra7-evm: Fix typo in SMPS6 (VDD_GPU) max voltage
ARM: OMAP2+: AM43x: Add ID for ES1.2
ARM: dts: am437x-sk: fix lcd enable pin mux data
ARM: dts: Fix gpmc regression for omap 2430sdp smc91x
hwmon: (tmp401) Detect TMP435 on all addresses it supports
mfd: rtsx: Add func to split u32 into register
mmc: sdhci-msm: Convert to mmc_send_tuning()
mmc: sdhci-esdhc-imx: Convert to mmc_send_tuning()
mmc: core: Let mmc_send_tuning() to take struct mmc_host* as parameter
nios2: Make NIOS2_CMDLINE_IGNORE_DTB depend on CMDLINE_BOOL
nios2: Add missing NR_CPUS to Kconfig
nios2: asm-offsets: Remove unused definition TI_TASK
nios2: Remove write-only struct member from nios2_timer
nios2: Remove unused extern declaration of shm_align_mask
nios2: include linux/type.h in io.h
nios2: move include asm-generic/io.h to end of file
nios2: remove include asm-generic/iomap.h from io.h
...
Diffstat (limited to 'drivers/md/persistent-data/dm-transaction-manager.c')
-rw-r--r-- | drivers/md/persistent-data/dm-transaction-manager.c | 77 |
1 files changed, 75 insertions, 2 deletions
diff --git a/drivers/md/persistent-data/dm-transaction-manager.c b/drivers/md/persistent-data/dm-transaction-manager.c index 3bc30a0ae3d6..9cb797d800cf 100644 --- a/drivers/md/persistent-data/dm-transaction-manager.c +++ b/drivers/md/persistent-data/dm-transaction-manager.c @@ -10,6 +10,8 @@ #include "dm-persistent-data-internal.h" #include <linux/export.h> +#include <linux/mutex.h> +#include <linux/hash.h> #include <linux/slab.h> #include <linux/device-mapper.h> @@ -17,6 +19,61 @@ /*----------------------------------------------------------------*/ +#define PREFETCH_SIZE 128 +#define PREFETCH_BITS 7 +#define PREFETCH_SENTINEL ((dm_block_t) -1ULL) + +struct prefetch_set { + struct mutex lock; + dm_block_t blocks[PREFETCH_SIZE]; +}; + +static unsigned prefetch_hash(dm_block_t b) +{ + return hash_64(b, PREFETCH_BITS); +} + +static void prefetch_wipe(struct prefetch_set *p) +{ + unsigned i; + for (i = 0; i < PREFETCH_SIZE; i++) + p->blocks[i] = PREFETCH_SENTINEL; +} + +static void prefetch_init(struct prefetch_set *p) +{ + mutex_init(&p->lock); + prefetch_wipe(p); +} + +static void prefetch_add(struct prefetch_set *p, dm_block_t b) +{ + unsigned h = prefetch_hash(b); + + mutex_lock(&p->lock); + if (p->blocks[h] == PREFETCH_SENTINEL) + p->blocks[h] = b; + + mutex_unlock(&p->lock); +} + +static void prefetch_issue(struct prefetch_set *p, struct dm_block_manager *bm) +{ + unsigned i; + + mutex_lock(&p->lock); + + for (i = 0; i < PREFETCH_SIZE; i++) + if (p->blocks[i] != PREFETCH_SENTINEL) { + dm_bm_prefetch(bm, p->blocks[i]); + p->blocks[i] = PREFETCH_SENTINEL; + } + + mutex_unlock(&p->lock); +} + +/*----------------------------------------------------------------*/ + struct shadow_info { struct hlist_node hlist; dm_block_t where; @@ -37,6 +94,8 @@ struct dm_transaction_manager { spinlock_t lock; struct hlist_head buckets[DM_HASH_SIZE]; + + struct prefetch_set prefetches; }; /*----------------------------------------------------------------*/ @@ -117,6 +176,8 @@ static struct dm_transaction_manager *dm_tm_create(struct dm_block_manager *bm, for (i = 0; i < DM_HASH_SIZE; i++) INIT_HLIST_HEAD(tm->buckets + i); + prefetch_init(&tm->prefetches); + return tm; } @@ -268,8 +329,14 @@ int dm_tm_read_lock(struct dm_transaction_manager *tm, dm_block_t b, struct dm_block_validator *v, struct dm_block **blk) { - if (tm->is_clone) - return dm_bm_read_try_lock(tm->real->bm, b, v, blk); + if (tm->is_clone) { + int r = dm_bm_read_try_lock(tm->real->bm, b, v, blk); + + if (r == -EWOULDBLOCK) + prefetch_add(&tm->real->prefetches, b); + + return r; + } return dm_bm_read_lock(tm->bm, b, v, blk); } @@ -317,6 +384,12 @@ struct dm_block_manager *dm_tm_get_bm(struct dm_transaction_manager *tm) return tm->bm; } +void dm_tm_issue_prefetches(struct dm_transaction_manager *tm) +{ + prefetch_issue(&tm->prefetches, tm->bm); +} +EXPORT_SYMBOL_GPL(dm_tm_issue_prefetches); + /*----------------------------------------------------------------*/ static int dm_tm_create_internal(struct dm_block_manager *bm, |