All of lore.kernel.org
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	stable@vger.kernel.org, Joe Thornber <ejt@redhat.com>,
	Mike Snitzer <snitzer@redhat.com>
Subject: [PATCH 3.14 15/77] dm cache: fix problematic dual use of a single migration count variable
Date: Tue, 27 Jan 2015 17:26:53 -0800	[thread overview]
Message-ID: <20150128012746.426128061@linuxfoundation.org> (raw)
In-Reply-To: <20150128012745.971137091@linuxfoundation.org>

3.14-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Joe Thornber <ejt@redhat.com>

commit a59db67656021fa212e9b95a583f13c34eb67cd9 upstream.

Introduce a new variable to count the number of allocated migration
structures.  The existing variable cache->nr_migrations became
overloaded.  It was used to:

 i) track of the number of migrations in flight for the purposes of
    quiescing during suspend.

 ii) to estimate the amount of background IO occuring.

Recent discard changes meant that REQ_DISCARD bios are processed with
a migration.  Discards are not background IO so nr_migrations was not
incremented.  However this could cause quiescing to complete early.

(i) is now handled with a new variable cache->nr_allocated_migrations.
cache->nr_migrations has been renamed cache->nr_io_migrations.
cleanup_migration() is now called free_io_migration(), since it
decrements that variable.

Also, remove the unused cache->next_migration variable that got replaced
with with prealloc_structs a while ago.

Signed-off-by: Joe Thornber <ejt@redhat.com>
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

---
 drivers/md/dm-cache-target.c |   89 ++++++++++++++++++++++++-------------------
 1 file changed, 50 insertions(+), 39 deletions(-)

--- a/drivers/md/dm-cache-target.c
+++ b/drivers/md/dm-cache-target.c
@@ -222,7 +222,13 @@ struct cache {
 	struct list_head need_commit_migrations;
 	sector_t migration_threshold;
 	wait_queue_head_t migration_wait;
-	atomic_t nr_migrations;
+	atomic_t nr_allocated_migrations;
+
+	/*
+	 * The number of in flight migrations that are performing
+	 * background io. eg, promotion, writeback.
+	 */
+	atomic_t nr_io_migrations;
 
 	wait_queue_head_t quiescing_wait;
 	atomic_t quiescing;
@@ -259,7 +265,6 @@ struct cache {
 	struct dm_deferred_set *all_io_ds;
 
 	mempool_t *migration_pool;
-	struct dm_cache_migration *next_migration;
 
 	struct dm_cache_policy *policy;
 	unsigned policy_nr_args;
@@ -350,10 +355,31 @@ static void free_prison_cell(struct cach
 	dm_bio_prison_free_cell(cache->prison, cell);
 }
 
+static struct dm_cache_migration *alloc_migration(struct cache *cache)
+{
+	struct dm_cache_migration *mg;
+
+	mg = mempool_alloc(cache->migration_pool, GFP_NOWAIT);
+	if (mg) {
+		mg->cache = cache;
+		atomic_inc(&mg->cache->nr_allocated_migrations);
+	}
+
+	return mg;
+}
+
+static void free_migration(struct dm_cache_migration *mg)
+{
+	if (atomic_dec_and_test(&mg->cache->nr_allocated_migrations))
+		wake_up(&mg->cache->migration_wait);
+
+	mempool_free(mg, mg->cache->migration_pool);
+}
+
 static int prealloc_data_structs(struct cache *cache, struct prealloc *p)
 {
 	if (!p->mg) {
-		p->mg = mempool_alloc(cache->migration_pool, GFP_NOWAIT);
+		p->mg = alloc_migration(cache);
 		if (!p->mg)
 			return -ENOMEM;
 	}
@@ -382,7 +408,7 @@ static void prealloc_free_structs(struct
 		free_prison_cell(cache, p->cell1);
 
 	if (p->mg)
-		mempool_free(p->mg, cache->migration_pool);
+		free_migration(p->mg);
 }
 
 static struct dm_cache_migration *prealloc_get_migration(struct prealloc *p)
@@ -812,24 +838,14 @@ static void remap_to_origin_then_cache(s
  * Migration covers moving data from the origin device to the cache, or
  * vice versa.
  *--------------------------------------------------------------*/
-static void free_migration(struct dm_cache_migration *mg)
-{
-	mempool_free(mg, mg->cache->migration_pool);
-}
-
-static void inc_nr_migrations(struct cache *cache)
+static void inc_io_migrations(struct cache *cache)
 {
-	atomic_inc(&cache->nr_migrations);
+	atomic_inc(&cache->nr_io_migrations);
 }
 
-static void dec_nr_migrations(struct cache *cache)
+static void dec_io_migrations(struct cache *cache)
 {
-	atomic_dec(&cache->nr_migrations);
-
-	/*
-	 * Wake the worker in case we're suspending the target.
-	 */
-	wake_up(&cache->migration_wait);
+	atomic_dec(&cache->nr_io_migrations);
 }
 
 static void __cell_defer(struct cache *cache, struct dm_bio_prison_cell *cell,
@@ -852,11 +868,10 @@ static void cell_defer(struct cache *cac
 	wake_worker(cache);
 }
 
-static void cleanup_migration(struct dm_cache_migration *mg)
+static void free_io_migration(struct dm_cache_migration *mg)
 {
-	struct cache *cache = mg->cache;
+	dec_io_migrations(mg->cache);
 	free_migration(mg);
-	dec_nr_migrations(cache);
 }
 
 static void migration_failure(struct dm_cache_migration *mg)
@@ -881,7 +896,7 @@ static void migration_failure(struct dm_
 		cell_defer(cache, mg->new_ocell, true);
 	}
 
-	cleanup_migration(mg);
+	free_io_migration(mg);
 }
 
 static void migration_success_pre_commit(struct dm_cache_migration *mg)
@@ -892,7 +907,7 @@ static void migration_success_pre_commit
 	if (mg->writeback) {
 		clear_dirty(cache, mg->old_oblock, mg->cblock);
 		cell_defer(cache, mg->old_ocell, false);
-		cleanup_migration(mg);
+		free_io_migration(mg);
 		return;
 
 	} else if (mg->demote) {
@@ -902,14 +917,14 @@ static void migration_success_pre_commit
 					     mg->old_oblock);
 			if (mg->promote)
 				cell_defer(cache, mg->new_ocell, true);
-			cleanup_migration(mg);
+			free_io_migration(mg);
 			return;
 		}
 	} else {
 		if (dm_cache_insert_mapping(cache->cmd, mg->cblock, mg->new_oblock)) {
 			DMWARN_LIMIT("promotion failed; couldn't update on disk metadata");
 			policy_remove_mapping(cache->policy, mg->new_oblock);
-			cleanup_migration(mg);
+			free_io_migration(mg);
 			return;
 		}
 	}
@@ -942,7 +957,7 @@ static void migration_success_post_commi
 		} else {
 			if (mg->invalidate)
 				policy_remove_mapping(cache->policy, mg->old_oblock);
-			cleanup_migration(mg);
+			free_io_migration(mg);
 		}
 
 	} else {
@@ -957,7 +972,7 @@ static void migration_success_post_commi
 			bio_endio(mg->new_ocell->holder, 0);
 			cell_defer(cache, mg->new_ocell, false);
 		}
-		cleanup_migration(mg);
+		free_io_migration(mg);
 	}
 }
 
@@ -1169,7 +1184,7 @@ static void promote(struct cache *cache,
 	mg->new_ocell = cell;
 	mg->start_jiffies = jiffies;
 
-	inc_nr_migrations(cache);
+	inc_io_migrations(cache);
 	quiesce_migration(mg);
 }
 
@@ -1192,7 +1207,7 @@ static void writeback(struct cache *cach
 	mg->new_ocell = NULL;
 	mg->start_jiffies = jiffies;
 
-	inc_nr_migrations(cache);
+	inc_io_migrations(cache);
 	quiesce_migration(mg);
 }
 
@@ -1218,7 +1233,7 @@ static void demote_then_promote(struct c
 	mg->new_ocell = new_ocell;
 	mg->start_jiffies = jiffies;
 
-	inc_nr_migrations(cache);
+	inc_io_migrations(cache);
 	quiesce_migration(mg);
 }
 
@@ -1245,7 +1260,7 @@ static void invalidate(struct cache *cac
 	mg->new_ocell = NULL;
 	mg->start_jiffies = jiffies;
 
-	inc_nr_migrations(cache);
+	inc_io_migrations(cache);
 	quiesce_migration(mg);
 }
 
@@ -1306,7 +1321,7 @@ static void process_discard_bio(struct c
 
 static bool spare_migration_bandwidth(struct cache *cache)
 {
-	sector_t current_volume = (atomic_read(&cache->nr_migrations) + 1) *
+	sector_t current_volume = (atomic_read(&cache->nr_io_migrations) + 1) *
 		cache->sectors_per_block;
 	return current_volume < cache->migration_threshold;
 }
@@ -1661,7 +1676,7 @@ static void stop_quiescing(struct cache
 
 static void wait_for_migrations(struct cache *cache)
 {
-	wait_event(cache->migration_wait, !atomic_read(&cache->nr_migrations));
+	wait_event(cache->migration_wait, !atomic_read(&cache->nr_allocated_migrations));
 }
 
 static void stop_worker(struct cache *cache)
@@ -1772,9 +1787,6 @@ static void destroy(struct cache *cache)
 {
 	unsigned i;
 
-	if (cache->next_migration)
-		mempool_free(cache->next_migration, cache->migration_pool);
-
 	if (cache->migration_pool)
 		mempool_destroy(cache->migration_pool);
 
@@ -2282,7 +2294,8 @@ static int cache_create(struct cache_arg
 	INIT_LIST_HEAD(&cache->quiesced_migrations);
 	INIT_LIST_HEAD(&cache->completed_migrations);
 	INIT_LIST_HEAD(&cache->need_commit_migrations);
-	atomic_set(&cache->nr_migrations, 0);
+	atomic_set(&cache->nr_allocated_migrations, 0);
+	atomic_set(&cache->nr_io_migrations, 0);
 	init_waitqueue_head(&cache->migration_wait);
 
 	init_waitqueue_head(&cache->quiescing_wait);
@@ -2342,8 +2355,6 @@ static int cache_create(struct cache_arg
 		goto bad;
 	}
 
-	cache->next_migration = NULL;
-
 	cache->need_tick_bio = true;
 	cache->sized = false;
 	cache->invalidate = false;



  parent reply	other threads:[~2015-01-28  2:43 UTC|newest]

Thread overview: 87+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-01-28  1:26 [PATCH 3.14 00/77] 3.14.31-stable review Greg Kroah-Hartman
2015-01-28  1:26 ` [PATCH 3.14 01/77] gpio: sysfs: fix gpio-chip device-attribute leak Greg Kroah-Hartman
2015-01-28  1:26 ` [PATCH 3.14 02/77] gpio: sysfs: fix gpio " Greg Kroah-Hartman
2015-01-28 14:30   ` Luis Henriques
2015-01-28 14:30     ` Luis Henriques
2015-01-28 15:24     ` Johan Hovold
2015-01-28 16:02       ` [PATCH v2] " Johan Hovold
2015-01-28 17:52         ` Greg Kroah-Hartman
2015-01-28  1:26 ` [PATCH 3.14 03/77] pinctrl: Fix two deadlocks Greg Kroah-Hartman
2015-01-28  1:26 ` [PATCH 3.14 04/77] libata: prevent HSM state change race between ISR and PIO Greg Kroah-Hartman
2015-01-28  1:26 ` [PATCH 3.14 05/77] ALSA: usb-audio: Add mic volume fix quirk for Logitech Webcam C210 Greg Kroah-Hartman
2015-01-28  1:26 ` [PATCH 3.14 06/77] scripts/recordmcount.pl: There is no -m32 gcc option on Super-H anymore Greg Kroah-Hartman
2015-01-28  1:26   ` Greg Kroah-Hartman
2015-01-28  1:26 ` [PATCH 3.14 07/77] drm/i915: Fix mutex->owner inspection race under DEBUG_MUTEXES Greg Kroah-Hartman
2015-01-28  1:26 ` [PATCH 3.14 08/77] drm/radeon: add a dpm quirk list Greg Kroah-Hartman
2015-01-28  1:26 ` [PATCH 3.14 09/77] drm/radeon: add si " Greg Kroah-Hartman
2015-01-28  1:26 ` [PATCH 3.14 10/77] drm/radeon: use rv515_ring_start on r5xx Greg Kroah-Hartman
2015-01-28  1:26 ` [PATCH 3.14 11/77] PCI: Add flag for devices where we cant use bus reset Greg Kroah-Hartman
2015-01-28  1:26 ` [PATCH 3.14 12/77] PCI: Mark Atheros AR93xx to avoid " Greg Kroah-Hartman
2015-01-28  1:26 ` [PATCH 3.14 13/77] ipr: wait for aborted command responses Greg Kroah-Hartman
2015-01-28  1:26 ` [PATCH 3.14 14/77] dm cache: share cache-metadata object across inactive and active DM tables Greg Kroah-Hartman
2015-01-28  1:26 ` Greg Kroah-Hartman [this message]
2015-01-28  1:26 ` [PATCH 3.14 16/77] time: settimeofday: Validate the values of tv from user Greg Kroah-Hartman
2015-01-28  1:26 ` [PATCH 3.14 17/77] time: adjtimex: Validate the ADJ_FREQUENCY values Greg Kroah-Hartman
2015-01-28  1:26 ` [PATCH 3.14 18/77] ARM: dts: imx25: Fix PWM "per" clocks Greg Kroah-Hartman
2015-01-28  1:26 ` [PATCH 3.14 19/77] bus: mvebu-mbus: fix support of MBus window 13 Greg Kroah-Hartman
2015-01-28  1:26 ` [PATCH 3.14 20/77] fix deadlock in cifs_ioctl_clone() Greg Kroah-Hartman
2015-01-28  1:26 ` [PATCH 3.14 21/77] can: dev: fix crtlmode_supported check Greg Kroah-Hartman
2015-01-28  1:27 ` [PATCH 3.14 22/77] clocksource: exynos_mct: Fix bitmask regression for exynos4_mct_write Greg Kroah-Hartman
2015-01-28  1:27 ` [PATCH 3.14 23/77] x86, hyperv: Mark the Hyper-V clocksource as being continuous Greg Kroah-Hartman
2015-01-28  1:27 ` [PATCH 3.14 24/77] x86/tsc: Change Fast TSC calibration failed from error to info Greg Kroah-Hartman
2015-01-28  1:27 ` [PATCH 3.14 25/77] x86, boot: Skip relocs when load address unchanged Greg Kroah-Hartman
2015-01-28  1:27 ` [PATCH 3.14 26/77] KVM: x86: Fix of previously incomplete fix for CVE-2014-8480 Greg Kroah-Hartman
2015-01-28  8:51   ` Nadav Amit
2015-01-28  1:27 ` [PATCH 3.14 27/77] x86, tls, ldt: Stop checking lm in LDT_empty Greg Kroah-Hartman
2015-01-28  1:27 ` [PATCH 3.14 28/77] x86, tls: Interpret an all-zero struct user_desc as "no segment" Greg Kroah-Hartman
2015-01-28  1:27 ` [PATCH 3.14 29/77] x86/apic: Re-enable PCI_MSI support for non-SMP X86_32 Greg Kroah-Hartman
2015-01-28  1:27 ` [PATCH 3.14 30/77] x86/asm/traps: Disable tracing and kprobes in fixup_bad_iret and sync_regs Greg Kroah-Hartman
2015-01-28  1:27 ` [PATCH 3.14 31/77] sata_dwc_460ex: fix resource leak on error path Greg Kroah-Hartman
2015-01-28  1:27 ` [PATCH 3.14 32/77] KEYS: close race between key lookup and freeing Greg Kroah-Hartman
2015-01-28  1:27 ` [PATCH 3.14 33/77] netfilter: nfnetlink: validate nfnetlink header from batch Greg Kroah-Hartman
2015-01-28  1:27 ` [PATCH 3.14 34/77] ipvs: uninitialized data with IP_VS_IPV6 Greg Kroah-Hartman
2015-01-28  1:27 ` [PATCH 3.14 35/77] Revert "swiotlb-xen: pass dev_addr to swiotlb_tbl_unmap_single" Greg Kroah-Hartman
2015-01-28  1:27 ` [PATCH 3.14 36/77] drbd: merge_bvec_fn: properly remap bvm->bi_bdev Greg Kroah-Hartman
2015-01-28  1:27 ` [PATCH 3.14 37/77] crypto: prefix module autoloading with "crypto-" Greg Kroah-Hartman
2015-01-28  1:27 ` [PATCH 3.14 38/77] crypto: include crypto- module prefix in template Greg Kroah-Hartman
2015-01-28  1:27 ` [PATCH 3.14 39/77] crypto: add missing crypto module aliases Greg Kroah-Hartman
2015-01-28  1:27 ` [PATCH 3.14 40/77] ARC: Delete stale barrier.h Greg Kroah-Hartman
2015-01-28  1:27 ` [PATCH 3.14 41/77] ARC: Fix build breakage for !CONFIG_ARC_DW2_UNWIND Greg Kroah-Hartman
2015-01-28  1:27 ` [PATCH 3.14 42/77] Input: evdev - fix EVIOCG{type} ioctl Greg Kroah-Hartman
2015-01-28  1:27 ` [PATCH 3.14 43/77] tty: Fix pty master poll() after slave closes v2 Greg Kroah-Hartman
2015-01-28  1:27 ` [PATCH 3.14 44/77] mmc: sdhci: Dont signal the sdio irq if its not setup Greg Kroah-Hartman
2015-01-28  1:27 ` [PATCH 3.14 45/77] mm/swap.c: clean up *lru_cache_add* functions Greg Kroah-Hartman
2015-01-28  1:27 ` [PATCH 3.14 46/77] mm: page_alloc: do not update zlc unless the zlc is active Greg Kroah-Hartman
2015-01-28  1:27 ` [PATCH 3.14 47/77] mm: page_alloc: do not treat a zone that cannot be used for dirty pages as "full" Greg Kroah-Hartman
2015-01-28  1:27 ` [PATCH 3.14 48/77] include/linux/jump_label.h: expose the reference count Greg Kroah-Hartman
2015-01-28  1:27 ` [PATCH 3.14 49/77] mm: page_alloc: use jump labels to avoid checking number_of_cpusets Greg Kroah-Hartman
2015-01-28  1:27 ` [PATCH 3.14 50/77] mm: page_alloc: calculate classzone_idx once from the zonelist ref Greg Kroah-Hartman
2015-01-28  1:27 ` [PATCH 3.14 51/77] mm: page_alloc: only check the zone id check if pages are buddies Greg Kroah-Hartman
2015-01-28  1:27 ` [PATCH 3.14 52/77] mm: page_alloc: only check the alloc flags and gfp_mask for dirty once Greg Kroah-Hartman
2015-01-28  1:27 ` [PATCH 3.14 53/77] mm: page_alloc: take the ALLOC_NO_WATERMARK check out of the fast path Greg Kroah-Hartman
2015-01-28  1:27 ` [PATCH 3.14 54/77] mm: page_alloc: use unsigned int for order in more places Greg Kroah-Hartman
2015-01-28  1:27 ` [PATCH 3.14 55/77] mm: page_alloc: reduce number of times page_to_pfn is called Greg Kroah-Hartman
2015-01-28  1:27 ` [PATCH 3.14 56/77] mm: page_alloc: convert hot/cold parameter and immediate callers to bool Greg Kroah-Hartman
2015-01-28  1:27 ` [PATCH 3.14 57/77] mm: page_alloc: lookup pageblock migratetype with IRQs enabled during free Greg Kroah-Hartman
2015-01-28  1:27 ` [PATCH 3.14 58/77] mm: shmem: avoid atomic operation during shmem_getpage_gfp Greg Kroah-Hartman
2015-01-28  1:27 ` [PATCH 3.14 59/77] mm: do not use atomic operations when releasing pages Greg Kroah-Hartman
2015-01-28  1:27 ` [PATCH 3.14 60/77] mm: do not use unnecessary atomic operations when adding pages to the LRU Greg Kroah-Hartman
2015-01-28  1:27 ` [PATCH 3.14 61/77] fs: buffer: do not use unnecessary atomic operations when discarding buffers Greg Kroah-Hartman
2015-01-28  1:27 ` [PATCH 3.14 62/77] mm: non-atomically mark page accessed during page cache allocation where possible Greg Kroah-Hartman
2015-01-28  1:27 ` [PATCH 3.14 63/77] mm: avoid unnecessary atomic operations during end_page_writeback() Greg Kroah-Hartman
2015-01-28  1:27 ` [PATCH 3.14 64/77] shmem: fix init_page_accessed use to stop !PageLRU bug Greg Kroah-Hartman
2015-01-28  1:27 ` [PATCH 3.14 65/77] mm/memory.c: use entry = ACCESS_ONCE(*pte) in handle_pte_fault() Greg Kroah-Hartman
2015-01-28  1:27 ` [PATCH 3.14 66/77] mm, thp: only collapse hugepages to nodes with affinity for zone_reclaim_mode Greg Kroah-Hartman
2015-01-28  1:27 ` [PATCH 3.14 67/77] mm: make copy_pte_range static again Greg Kroah-Hartman
2015-01-28  1:27 ` [PATCH 3.14 68/77] vmalloc: use rcu list iterator to reduce vmap_area_lock contention Greg Kroah-Hartman
2015-01-28  1:27 ` [PATCH 3.14 69/77] memcg, vmscan: Fix forced scan of anonymous pages Greg Kroah-Hartman
2015-01-28  1:27 ` [PATCH 3.14 70/77] mm: pagemap: avoid unnecessary overhead when tracepoints are deactivated Greg Kroah-Hartman
2015-01-28  1:27 ` [PATCH 3.14 71/77] mm: rearrange zone fields into read-only, page alloc, statistics and page reclaim lines Greg Kroah-Hartman
2015-01-28  1:27 ` [PATCH 3.14 72/77] mm: move zone->pages_scanned into a vmstat counter Greg Kroah-Hartman
2015-01-28  1:27 ` [PATCH 3.14 73/77] mm: vmscan: only update per-cpu thresholds for online CPU Greg Kroah-Hartman
2015-01-28  1:27 ` [PATCH 3.14 74/77] mm: page_alloc: abort fair zone allocation policy when remotes nodes are encountered Greg Kroah-Hartman
2015-01-28  1:27 ` [PATCH 3.14 75/77] mm: page_alloc: reduce cost of the fair zone allocation policy Greg Kroah-Hartman
2015-01-28  1:27 ` [PATCH 3.14 76/77] mm: get rid of radix tree gfp mask for pagecache_get_page Greg Kroah-Hartman
2015-01-28  1:27 ` [PATCH 3.14 77/77] md/raid5: fetch_block must fetch all the blocks handle_stripe_dirtying wants Greg Kroah-Hartman
2015-01-28 14:15 ` [PATCH 3.14 00/77] 3.14.31-stable review Guenter Roeck
2015-01-28 16:51 ` Shuah Khan

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20150128012746.426128061@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=ejt@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=snitzer@redhat.com \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.