diff options
| author | Srinivasarao P <spathi@codeaurora.org> | 2019-01-29 15:49:08 +0530 |
|---|---|---|
| committer | Srinivasarao P <spathi@codeaurora.org> | 2019-01-29 16:37:33 +0530 |
| commit | dd21e159de67974e3de0791a7175edb4fb2ce7a1 (patch) | |
| tree | 92bfc66c2fe47144ecae85e8425ab25d7728a3df /drivers/md | |
| parent | cf61d4f2ea8417b5686926524842159e9f24ebd0 (diff) | |
| parent | b3e9e81ee06831ae8c3e7ccfd27b2337ae2ff114 (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.c | 19 | ||||
| -rw-r--r-- | drivers/md/dm-snap.c | 22 | ||||
| -rw-r--r-- | drivers/md/dm-table.c | 3 |
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) |
