summaryrefslogtreecommitdiff
path: root/drivers/md
diff options
context:
space:
mode:
authorSrinivasarao P <spathi@codeaurora.org>2019-01-29 15:49:08 +0530
committerSrinivasarao P <spathi@codeaurora.org>2019-01-29 16:37:33 +0530
commitdd21e159de67974e3de0791a7175edb4fb2ce7a1 (patch)
tree92bfc66c2fe47144ecae85e8425ab25d7728a3df /drivers/md
parentcf61d4f2ea8417b5686926524842159e9f24ebd0 (diff)
parentb3e9e81ee06831ae8c3e7ccfd27b2337ae2ff114 (diff)
Merge android-4.4.172 (b3e9e81) into msm-4.4
* refs/heads/tmp-b3e9e81 Linux 4.4.172 ipmi:ssif: Fix handling of multi-part return messages net: speed up skb_rbtree_purge() mm, proc: be more verbose about unstable VMA flags in /proc/<pid>/smaps mm/page-writeback.c: don't break integrity writeback on ->writepage() error ocfs2: fix panic due to unrecovered local alloc scsi: megaraid: fix out-of-bound array accesses sysfs: Disable lockdep for driver bind/unbind files ALSA: bebob: fix model-id of unit for Apogee Ensemble dm snapshot: Fix excessive memory usage and workqueue stalls dm kcopyd: Fix bug causing workqueue stalls perf parse-events: Fix unchecked usage of strncpy() perf svghelper: Fix unchecked usage of strncpy() perf intel-pt: Fix error with config term "pt=0" mmc: atmel-mci: do not assume idle after atmci_request_end kconfig: fix memory leak when EOF is encountered in quotation kconfig: fix file name and line number of warn_ignored_character() clk: imx6q: reset exclusive gates on init scsi: target: use consistent left-aligned ASCII INQUIRY data net: call sk_dst_reset when set SO_DONTROUTE media: firewire: Fix app_info parameter type in avc_ca{,_app}_info powerpc/pseries/cpuidle: Fix preempt warning pstore/ram: Do not treat empty buffers as valid jffs2: Fix use of uninitialized delayed_work, lockdep breakage arm64: perf: set suppress_bind_attrs flag to true MIPS: SiByte: Enable swiotlb for SWARM, LittleSur and BigSur writeback: don't decrement wb->refcnt if !wb->bdi e1000e: allow non-monotonic SYSTIM readings platform/x86: asus-wmi: Tell the EC the OS will handle the display off hotkey xfs: don't fail when converting shortform attr to long form during ATTR_REPLACE ipv6: Take rcu_read_lock in __inet6_bind for mapped addresses ipv6: Consider sk_bound_dev_if when binding a socket to a v4 mapped address r8169: Add support for new Realtek Ethernet media: vb2: be sure to unlock mutex on errors drm/fb-helper: Ignore the value of fb_var_screeninfo.pixclock loop: Fix double mutex_unlock(&loop_ctl_mutex) in loop_control_ioctl() loop: Get rid of loop_index_mutex loop: Fold __loop_release into loop_release block/loop: Use global lock for ioctl() operation. tipc: fix uninit-value in tipc_nl_compat_doit tipc: fix uninit-value in tipc_nl_compat_name_table_dump tipc: fix uninit-value in tipc_nl_compat_link_set tipc: fix uninit-value in tipc_nl_compat_bearer_enable tipc: fix uninit-value in tipc_nl_compat_link_reset_stats sctp: allocate sctp_sockaddr_entry with kzalloc selinux: fix GPF on invalid policy sunrpc: handle ENOMEM in rpcb_getport_async media: vb2: vb2_mmap: move lock up LSM: Check for NULL cred-security on free media: vivid: set min width/height to a value > 0 media: vivid: fix error handling of kthread_run omap2fb: Fix stack memory disclosure Disable MSI also when pcie-octeon.pcie_disable on mfd: tps6586x: Handle interrupts on suspend mips: fix n32 compat_ipc_parse_version scsi: sd: Fix cache_type_store() Yama: Check for pid death before checking ancestry btrfs: wait on ordered extents on abort cleanup crypto: authenc - fix parsing key with misaligned rta_len crypto: authencesn - Avoid twice completion call in decrypt path ip: on queued skb use skb_header_pointer instead of pskb_may_pull packet: Do not leak dev refcounts on error exit net: bridge: fix a bug on using a neighbour cache entry without checking its state ipv6: fix kernel-infoleak in ipv6_local_error() arm64: Don't trap host pointer auth use to EL2 arm64/kvm: consistently handle host HCR_EL2 flags proc: Remove empty line in /proc/self/status media: em28xx: Fix misplaced reset of dev->v4l::field_count f2fs: fix validation of the block count in sanity_check_raw_super f2fs: fix missing up_read f2fs: fix invalid memory access f2fs: fix to do sanity check with cp_pack_start_sum f2fs: fix to do sanity check with block address in main area v2 f2fs: fix to do sanity check with block address in main area f2fs: fix to do sanity check with reserved blkaddr of inline inode f2fs: fix to do sanity check with node footer and iblocks f2fs: Add sanity_check_inode() function f2fs: fix to do sanity check with user_block_count f2fs: fix to do sanity check with secs_per_zone f2fs: introduce and spread verify_blkaddr f2fs: clean up with is_valid_blkaddr() f2fs: enhance sanity_check_raw_super() to avoid potential overflow f2fs: sanity check on sit entry f2fs: check blkaddr more accuratly before issue a bio f2fs: return error during fill_super f2fs: fix race condition in between free nid allocator/initializer f2fs: free meta pages if sanity check for ckpt is failed f2fs: detect wrong layout f2fs: fix to determine start_cp_addr by sbi->cur_cp_pack f2fs: put directory inodes before checkpoint in roll-forward recovery f2fs: introduce get_checkpoint_version for cleanup f2fs: use crc and cp version to determine roll-forward recovery f2fs: avoid unneeded loop in build_sit_entries f2fs: not allow to write illegal blkaddr f2fs: fix to avoid reading out encrypted data in page cache f2fs: fix inode cache leak f2fs: factor out fsync inode entry operations f2fs: remove an obsolete variable f2fs: give -EINVAL for norecovery and rw mount f2fs: fix to convert inline directory correctly f2fs: move sanity checking of cp into get_valid_checkpoint f2fs: cover more area with nat_tree_lock f2fs: clean up argument of recover_data can: gw: ensure DLC boundaries after CAN frame modification tty/ldsem: Wake up readers after timed out down_write() UPSTREAM: dm: do not allow readahead to limit IO size UPSTREAM: readahead: stricter check for bdi io_pages UPSTREAM: mm: don't cap request size based on read-ahead setting ANDROID: Fix cuttlefish redundant vsock connection. UPSTREAM: loop: drop caches if offset or block_size are changed Conflicts: arch/arm64/kvm/hyp.S Fixed compilation issue due to variable 'backing_dev_info', which got changed to pointer in downstream. Change-Id: I8baa569fe9fc13ed5a7e863e5ad1fb8cf1cd469e Signed-off-by: Srinivasarao P <spathi@codeaurora.org>
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/dm-kcopyd.c19
-rw-r--r--drivers/md/dm-snap.c22
-rw-r--r--drivers/md/dm-table.c3
3 files changed, 39 insertions, 5 deletions
diff --git a/drivers/md/dm-kcopyd.c b/drivers/md/dm-kcopyd.c
index 54c308e6704f..04248394843e 100644
--- a/drivers/md/dm-kcopyd.c
+++ b/drivers/md/dm-kcopyd.c
@@ -55,15 +55,17 @@ struct dm_kcopyd_client {
struct dm_kcopyd_throttle *throttle;
/*
- * We maintain three lists of jobs:
+ * We maintain four lists of jobs:
*
* i) jobs waiting for pages
* ii) jobs that have pages, and are waiting for the io to be issued.
- * iii) jobs that have completed.
+ * iii) jobs that don't need to do any IO and just run a callback
+ * iv) jobs that have completed.
*
- * All three of these are protected by job_lock.
+ * All four of these are protected by job_lock.
*/
spinlock_t job_lock;
+ struct list_head callback_jobs;
struct list_head complete_jobs;
struct list_head io_jobs;
struct list_head pages_jobs;
@@ -583,6 +585,7 @@ static void do_work(struct work_struct *work)
struct dm_kcopyd_client *kc = container_of(work,
struct dm_kcopyd_client, kcopyd_work);
struct blk_plug plug;
+ unsigned long flags;
/*
* The order that these are called is *very* important.
@@ -591,6 +594,10 @@ static void do_work(struct work_struct *work)
* list. io jobs call wake when they complete and it all
* starts again.
*/
+ spin_lock_irqsave(&kc->job_lock, flags);
+ list_splice_tail_init(&kc->callback_jobs, &kc->complete_jobs);
+ spin_unlock_irqrestore(&kc->job_lock, flags);
+
blk_start_plug(&plug);
process_jobs(&kc->complete_jobs, kc, run_complete_job);
process_jobs(&kc->pages_jobs, kc, run_pages_job);
@@ -608,7 +615,7 @@ static void dispatch_job(struct kcopyd_job *job)
struct dm_kcopyd_client *kc = job->kc;
atomic_inc(&kc->nr_jobs);
if (unlikely(!job->source.count))
- push(&kc->complete_jobs, job);
+ push(&kc->callback_jobs, job);
else if (job->pages == &zero_page_list)
push(&kc->io_jobs, job);
else
@@ -795,7 +802,7 @@ void dm_kcopyd_do_callback(void *j, int read_err, unsigned long write_err)
job->read_err = read_err;
job->write_err = write_err;
- push(&kc->complete_jobs, job);
+ push(&kc->callback_jobs, job);
wake(kc);
}
EXPORT_SYMBOL(dm_kcopyd_do_callback);
@@ -825,6 +832,7 @@ struct dm_kcopyd_client *dm_kcopyd_client_create(struct dm_kcopyd_throttle *thro
return ERR_PTR(-ENOMEM);
spin_lock_init(&kc->job_lock);
+ INIT_LIST_HEAD(&kc->callback_jobs);
INIT_LIST_HEAD(&kc->complete_jobs);
INIT_LIST_HEAD(&kc->io_jobs);
INIT_LIST_HEAD(&kc->pages_jobs);
@@ -874,6 +882,7 @@ void dm_kcopyd_client_destroy(struct dm_kcopyd_client *kc)
/* Wait for completion of all jobs submitted by this client. */
wait_event(kc->destroyq, !atomic_read(&kc->nr_jobs));
+ BUG_ON(!list_empty(&kc->callback_jobs));
BUG_ON(!list_empty(&kc->complete_jobs));
BUG_ON(!list_empty(&kc->io_jobs));
BUG_ON(!list_empty(&kc->pages_jobs));
diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c
index e4d1bafe78c1..2a855e5429ab 100644
--- a/drivers/md/dm-snap.c
+++ b/drivers/md/dm-snap.c
@@ -19,6 +19,7 @@
#include <linux/vmalloc.h>
#include <linux/log2.h>
#include <linux/dm-kcopyd.h>
+#include <linux/semaphore.h>
#include "dm.h"
@@ -105,6 +106,9 @@ struct dm_snapshot {
/* The on disk metadata handler */
struct dm_exception_store *store;
+ /* Maximum number of in-flight COW jobs. */
+ struct semaphore cow_count;
+
struct dm_kcopyd_client *kcopyd_client;
/* Wait for events based on state_bits */
@@ -145,6 +149,19 @@ struct dm_snapshot {
#define RUNNING_MERGE 0
#define SHUTDOWN_MERGE 1
+/*
+ * Maximum number of chunks being copied on write.
+ *
+ * The value was decided experimentally as a trade-off between memory
+ * consumption, stalling the kernel's workqueues and maintaining a high enough
+ * throughput.
+ */
+#define DEFAULT_COW_THRESHOLD 2048
+
+static int cow_threshold = DEFAULT_COW_THRESHOLD;
+module_param_named(snapshot_cow_threshold, cow_threshold, int, 0644);
+MODULE_PARM_DESC(snapshot_cow_threshold, "Maximum number of chunks being copied on write");
+
DECLARE_DM_KCOPYD_THROTTLE_WITH_MODULE_PARM(snapshot_copy_throttle,
"A percentage of time allocated for copy on write");
@@ -1189,6 +1206,8 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
goto bad_hash_tables;
}
+ sema_init(&s->cow_count, (cow_threshold > 0) ? cow_threshold : INT_MAX);
+
s->kcopyd_client = dm_kcopyd_client_create(&dm_kcopyd_throttle);
if (IS_ERR(s->kcopyd_client)) {
r = PTR_ERR(s->kcopyd_client);
@@ -1560,6 +1579,7 @@ static void copy_callback(int read_err, unsigned long write_err, void *context)
}
list_add(&pe->out_of_order_entry, lh);
}
+ up(&s->cow_count);
}
/*
@@ -1583,6 +1603,7 @@ static void start_copy(struct dm_snap_pending_exception *pe)
dest.count = src.count;
/* Hand over to kcopyd */
+ down(&s->cow_count);
dm_kcopyd_copy(s->kcopyd_client, &src, 1, &dest, 0, copy_callback, pe);
}
@@ -1602,6 +1623,7 @@ static void start_full_bio(struct dm_snap_pending_exception *pe,
pe->full_bio = bio;
pe->full_bio_end_io = bio->bi_end_io;
+ down(&s->cow_count);
callback_data = dm_kcopyd_prepare_callback(s->kcopyd_client,
copy_callback, pe);
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
index 48b09dedd0fb..52f261381b0c 100644
--- a/drivers/md/dm-table.c
+++ b/drivers/md/dm-table.c
@@ -1542,6 +1542,9 @@ void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q,
smp_mb();
if (dm_table_request_based(t))
queue_flag_set_unlocked(QUEUE_FLAG_STACKABLE, q);
+
+ /* io_pages is used for readahead */
+ q->backing_dev_info->io_pages = limits->max_sectors >> (PAGE_SHIFT - 9);
}
unsigned int dm_table_get_num_targets(struct dm_table *t)