Merge branch 'akpm' (patches from Andrew)
Merge updates from Andrew Morton: "Am experimenting with splitting MM up into identifiable subsystems perhaps with a view to gitifying it in complex ways. Also with more verbose "incoming" emails. Most of MM is here and a few other trees. Subsystems affected by this patch series: - hotfixes - iommu - scripts - arch/sh - ocfs2 - mm:slab-generic - mm:slub - mm:kmemleak - mm:kasan - mm:cleanups - mm:debug - mm:pagecache - mm:swap - mm:memcg - mm:gup - mm:pagemap - mm:infrastructure - mm:vmalloc - mm:initialization - mm:pagealloc - mm:vmscan - mm:tools - mm:proc - mm:ras - mm:oom-kill hotfixes: mm: vmscan: scan anonymous pages on file refaults mm/nvdimm: add is_ioremap_addr and use that to check ioremap address mm/memcontrol: fix wrong statistics in memory.stat mm/z3fold.c: lock z3fold page before __SetPageMovable() nilfs2: do not use unexported cpu_to_le32()/le32_to_cpu() in uapi header MAINTAINERS: nilfs2: update email address iommu: include/linux/dmar.h: replace single-char identifiers in macros scripts: scripts/decode_stacktrace: match basepath using shell prefix operator, not regex scripts/decode_stacktrace: look for modules with .ko.debug extension scripts/spelling.txt: drop "sepc" from the misspelling list scripts/spelling.txt: add spelling fix for prohibited scripts/decode_stacktrace: Accept dash/underscore in modules scripts/spelling.txt: add more spellings to spelling.txt arch/sh: arch/sh/configs/sdk7786_defconfig: remove CONFIG_LOGFS sh: config: remove left-over BACKLIGHT_LCD_SUPPORT sh: prevent warnings when using iounmap ocfs2: fs: ocfs: fix spelling mistake "hearbeating" -> "heartbeat" ocfs2/dlm: use struct_size() helper ocfs2: add last unlock times in locking_state ocfs2: add locking filter debugfs file ocfs2: add first lock wait time in locking_state ocfs: no need to check return value of debugfs_create functions fs/ocfs2/dlmglue.c: unneeded variable: "status" ocfs2: use kmemdup rather than duplicating its implementation mm:slab-generic: Patch series "mm/slab: Improved sanity checking": mm/slab: validate cache membership under freelist hardening mm/slab: sanity-check page type when looking up cache lkdtm/heap: add tests for freelist hardening mm:slub: mm/slub.c: avoid double string traverse in kmem_cache_flags() slub: don't panic for memcg kmem cache creation failure mm:kmemleak: mm/kmemleak.c: fix check for softirq context mm/kmemleak.c: change error at _write when kmemleak is disabled docs: kmemleak: add more documentation details mm:kasan: mm/kasan: print frame description for stack bugs Patch series "Bitops instrumentation for KASAN", v5: lib/test_kasan: add bitops tests x86: use static_cpu_has in uaccess region to avoid instrumentation asm-generic, x86: add bitops instrumentation for KASAN Patch series "mm/kasan: Add object validation in ksize()", v3: mm/kasan: introduce __kasan_check_{read,write} mm/kasan: change kasan_check_{read,write} to return boolean lib/test_kasan: Add test for double-kzfree detection mm/slab: refactor common ksize KASAN logic into slab_common.c mm/kasan: add object validation in ksize() mm:cleanups: include/linux/pfn_t.h: remove pfn_t_to_virt() Patch series "remove ARCH_SELECT_MEMORY_MODEL where it has no effect": arm: remove ARCH_SELECT_MEMORY_MODEL s390: remove ARCH_SELECT_MEMORY_MODEL sparc: remove ARCH_SELECT_MEMORY_MODEL mm/gup.c: make follow_page_mask() static mm/memory.c: trivial clean up in insert_page() mm: make !CONFIG_HUGE_PAGE wrappers into static inlines include/linux/mm_types.h: ifdef struct vm_area_struct::swap_readahead_info mm: remove the account_page_dirtied export mm/page_isolation.c: change the prototype of undo_isolate_page_range() include/linux/vmpressure.h: use spinlock_t instead of struct spinlock mm: remove the exporting of totalram_pages include/linux/pagemap.h: document trylock_page() return value mm:debug: mm/failslab.c: by default, do not fail allocations with direct reclaim only Patch series "debug_pagealloc improvements": mm, debug_pagelloc: use static keys to enable debugging mm, page_alloc: more extensive free page checking with debug_pagealloc mm, debug_pagealloc: use a page type instead of page_ext flag mm:pagecache: Patch series "fix filler_t callback type mismatches", v2: mm/filemap.c: fix an overly long line in read_cache_page mm/filemap: don't cast ->readpage to filler_t for do_read_cache_page jffs2: pass the correct prototype to read_cache_page 9p: pass the correct prototype to read_cache_page mm/filemap.c: correct the comment about VM_FAULT_RETRY mm:swap: mm, swap: fix race between swapoff and some swap operations mm/swap_state.c: simplify total_swapcache_pages() with get_swap_device() mm, swap: use rbtree for swap_extent mm/mincore.c: fix race between swapoff and mincore mm:memcg: memcg, oom: no oom-kill for __GFP_RETRY_MAYFAIL memcg, fsnotify: no oom-kill for remote memcg charging mm, memcg: introduce memory.events.local mm: memcontrol: dump memory.stat during cgroup OOM Patch series "mm: reparent slab memory on cgroup removal", v7: mm: memcg/slab: postpone kmem_cache memcg pointer initialization to memcg_link_cache() mm: memcg/slab: rename slab delayed deactivation functions and fields mm: memcg/slab: generalize postponed non-root kmem_cache deactivation mm: memcg/slab: introduce __memcg_kmem_uncharge_memcg() mm: memcg/slab: unify SLAB and SLUB page accounting mm: memcg/slab: don't check the dying flag on kmem_cache creation mm: memcg/slab: synchronize access to kmem_cache dying flag using a spinlock mm: memcg/slab: rework non-root kmem_cache lifecycle management mm: memcg/slab: stop setting page->mem_cgroup pointer for slab pages mm: memcg/slab: reparent memcg kmem_caches on cgroup removal mm, memcg: add a memcg_slabinfo debugfs file mm:gup: Patch series "switch the remaining architectures to use generic GUP", v4: mm: use untagged_addr() for get_user_pages_fast addresses mm: simplify gup_fast_permitted mm: lift the x86_32 PAE version of gup_get_pte to common code MIPS: use the generic get_user_pages_fast code sh: add the missing pud_page definition sh: use the generic get_user_pages_fast code sparc64: add the missing pgd_page definition sparc64: define untagged_addr() sparc64: use the generic get_user_pages_fast code mm: rename CONFIG_HAVE_GENERIC_GUP to CONFIG_HAVE_FAST_GUP mm: reorder code blocks in gup.c mm: consolidate the get_user_pages* implementations mm: validate get_user_pages_fast flags mm: move the powerpc hugepd code to mm/gup.c mm: switch gup_hugepte to use try_get_compound_head mm: mark the page referenced in gup_hugepte mm/gup: speed up check_and_migrate_cma_pages() on huge page mm/gup.c: remove some BUG_ONs from get_gate_page() mm/gup.c: mark undo_dev_pagemap as __maybe_unused mm:pagemap: asm-generic, x86: introduce generic pte_{alloc,free}_one[_kernel] alpha: switch to generic version of pte allocation arm: switch to generic version of pte allocation arm64: switch to generic version of pte allocation csky: switch to generic version of pte allocation m68k: sun3: switch to generic version of pte allocation mips: switch to generic version of pte allocation nds32: switch to generic version of pte allocation nios2: switch to generic version of pte allocation parisc: switch to generic version of pte allocation riscv: switch to generic version of pte allocation um: switch to generic version of pte allocation unicore32: switch to generic version of pte allocation mm/pgtable: drop pgtable_t variable from pte_fn_t functions mm/memory.c: fail when offset == num in first check of __vm_map_pages() mm:infrastructure: mm/mmu_notifier: use hlist_add_head_rcu() mm:vmalloc: Patch series "Some cleanups for the KVA/vmalloc", v5: mm/vmalloc.c: remove "node" argument mm/vmalloc.c: preload a CPU with one object for split purpose mm/vmalloc.c: get rid of one single unlink_va() when merge mm/vmalloc.c: switch to WARN_ON() and move it under unlink_va() mm/vmalloc.c: spelling> s/informaion/information/ mm:initialization: mm/large system hash: use vmalloc for size > MAX_ORDER when !hashdist mm/large system hash: clear hashdist when only one node with memory is booted mm:pagealloc: arm64: move jump_label_init() before parse_early_param() Patch series "add init_on_alloc/init_on_free boot options", v10: mm: security: introduce init_on_alloc=1 and init_on_free=1 boot options mm: init: report memory auto-initialization features at boot time mm:vmscan: mm: vmscan: remove double slab pressure by inc'ing sc->nr_scanned mm: vmscan: correct some vmscan counters for THP swapout mm:tools: tools/vm/slabinfo: order command line options tools/vm/slabinfo: add partial slab listing to -X tools/vm/slabinfo: add option to sort by partial slabs tools/vm/slabinfo: add sorting info to help menu mm:proc: proc: use down_read_killable mmap_sem for /proc/pid/maps proc: use down_read_killable mmap_sem for /proc/pid/smaps_rollup proc: use down_read_killable mmap_sem for /proc/pid/pagemap proc: use down_read_killable mmap_sem for /proc/pid/clear_refs proc: use down_read_killable mmap_sem for /proc/pid/map_files mm: use down_read_killable for locking mmap_sem in access_remote_vm mm: smaps: split PSS into components mm: vmalloc: show number of vmalloc pages in /proc/meminfo mm:ras: mm/memory-failure.c: clarify error message mm:oom-kill: mm: memcontrol: use CSS_TASK_ITER_PROCS at mem_cgroup_scan_tasks() mm, oom: refactor dump_tasks for memcg OOMs mm, oom: remove redundant task_in_mem_cgroup() check oom: decouple mems_allowed from oom_unkillable_task mm/oom_kill.c: remove redundant OOM score normalization in select_bad_process()" * akpm: (147 commits) mm/oom_kill.c: remove redundant OOM score normalization in select_bad_process() oom: decouple mems_allowed from oom_unkillable_task mm, oom: remove redundant task_in_mem_cgroup() check mm, oom: refactor dump_tasks for memcg OOMs mm: memcontrol: use CSS_TASK_ITER_PROCS at mem_cgroup_scan_tasks() mm/memory-failure.c: clarify error message mm: vmalloc: show number of vmalloc pages in /proc/meminfo mm: smaps: split PSS into components mm: use down_read_killable for locking mmap_sem in access_remote_vm proc: use down_read_killable mmap_sem for /proc/pid/map_files proc: use down_read_killable mmap_sem for /proc/pid/clear_refs proc: use down_read_killable mmap_sem for /proc/pid/pagemap proc: use down_read_killable mmap_sem for /proc/pid/smaps_rollup proc: use down_read_killable mmap_sem for /proc/pid/maps tools/vm/slabinfo: add sorting info to help menu tools/vm/slabinfo: add option to sort by partial slabs tools/vm/slabinfo: add partial slab listing to -X tools/vm/slabinfo: order command line options mm: vmscan: correct some vmscan counters for THP swapout mm: vmscan: remove double slab pressure by inc'ing sc->nr_scanned ...
此提交包含在:
@@ -35,8 +35,9 @@
|
||||
* @page: structure to page
|
||||
*
|
||||
*/
|
||||
static int v9fs_fid_readpage(struct p9_fid *fid, struct page *page)
|
||||
static int v9fs_fid_readpage(void *data, struct page *page)
|
||||
{
|
||||
struct p9_fid *fid = data;
|
||||
struct inode *inode = page->mapping->host;
|
||||
struct bio_vec bvec = {.bv_page = page, .bv_len = PAGE_SIZE};
|
||||
struct iov_iter to;
|
||||
@@ -107,7 +108,8 @@ static int v9fs_vfs_readpages(struct file *filp, struct address_space *mapping,
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
|
||||
ret = read_cache_pages(mapping, pages, (void *)v9fs_vfs_readpage, filp);
|
||||
ret = read_cache_pages(mapping, pages, v9fs_fid_readpage,
|
||||
filp->private_data);
|
||||
p9_debug(P9_DEBUG_VFS, " = %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
@@ -109,9 +109,9 @@ static int jffs2_do_readpage_nolock (struct inode *inode, struct page *pg)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int jffs2_do_readpage_unlock(struct inode *inode, struct page *pg)
|
||||
int jffs2_do_readpage_unlock(void *data, struct page *pg)
|
||||
{
|
||||
int ret = jffs2_do_readpage_nolock(inode, pg);
|
||||
int ret = jffs2_do_readpage_nolock(data, pg);
|
||||
unlock_page(pg);
|
||||
return ret;
|
||||
}
|
||||
|
@@ -687,7 +687,7 @@ unsigned char *jffs2_gc_fetch_page(struct jffs2_sb_info *c,
|
||||
struct page *pg;
|
||||
|
||||
pg = read_cache_page(inode->i_mapping, offset >> PAGE_SHIFT,
|
||||
(void *)jffs2_do_readpage_unlock, inode);
|
||||
jffs2_do_readpage_unlock, inode);
|
||||
if (IS_ERR(pg))
|
||||
return (void *)pg;
|
||||
|
||||
|
@@ -155,7 +155,7 @@ extern const struct file_operations jffs2_file_operations;
|
||||
extern const struct inode_operations jffs2_file_inode_operations;
|
||||
extern const struct address_space_operations jffs2_file_address_operations;
|
||||
int jffs2_fsync(struct file *, loff_t, loff_t, int);
|
||||
int jffs2_do_readpage_unlock (struct inode *inode, struct page *pg);
|
||||
int jffs2_do_readpage_unlock(void *data, struct page *pg);
|
||||
|
||||
/* ioctl.c */
|
||||
long jffs2_ioctl(struct file *, unsigned int, unsigned long);
|
||||
|
@@ -288,10 +288,13 @@ struct fanotify_event *fanotify_alloc_event(struct fsnotify_group *group,
|
||||
/*
|
||||
* For queues with unlimited length lost events are not expected and
|
||||
* can possibly have security implications. Avoid losing events when
|
||||
* memory is short.
|
||||
* memory is short. For the limited size queues, avoid OOM killer in the
|
||||
* target monitoring memcg as it may have security repercussion.
|
||||
*/
|
||||
if (group->max_events == UINT_MAX)
|
||||
gfp |= __GFP_NOFAIL;
|
||||
else
|
||||
gfp |= __GFP_RETRY_MAYFAIL;
|
||||
|
||||
/* Whoever is interested in the event, pays for the allocation. */
|
||||
memalloc_use_memcg(group->memcg);
|
||||
|
@@ -90,9 +90,13 @@ int inotify_handle_event(struct fsnotify_group *group,
|
||||
i_mark = container_of(inode_mark, struct inotify_inode_mark,
|
||||
fsn_mark);
|
||||
|
||||
/* Whoever is interested in the event, pays for the allocation. */
|
||||
/*
|
||||
* Whoever is interested in the event, pays for the allocation. Do not
|
||||
* trigger OOM killer in the target monitoring memcg as it may have
|
||||
* security repercussion.
|
||||
*/
|
||||
memalloc_use_memcg(group->memcg);
|
||||
event = kmalloc(alloc_len, GFP_KERNEL_ACCOUNT);
|
||||
event = kmalloc(alloc_len, GFP_KERNEL_ACCOUNT | __GFP_RETRY_MAYFAIL);
|
||||
memalloc_unuse_memcg();
|
||||
|
||||
if (unlikely(!event)) {
|
||||
|
@@ -6191,17 +6191,17 @@ int ocfs2_begin_truncate_log_recovery(struct ocfs2_super *osb,
|
||||
if (le16_to_cpu(tl->tl_used)) {
|
||||
trace_ocfs2_truncate_log_recovery_num(le16_to_cpu(tl->tl_used));
|
||||
|
||||
*tl_copy = kmalloc(tl_bh->b_size, GFP_KERNEL);
|
||||
/*
|
||||
* Assuming the write-out below goes well, this copy will be
|
||||
* passed back to recovery for processing.
|
||||
*/
|
||||
*tl_copy = kmemdup(tl_bh->b_data, tl_bh->b_size, GFP_KERNEL);
|
||||
if (!(*tl_copy)) {
|
||||
status = -ENOMEM;
|
||||
mlog_errno(status);
|
||||
goto bail;
|
||||
}
|
||||
|
||||
/* Assuming the write-out below goes well, this copy
|
||||
* will be passed back to recovery for processing. */
|
||||
memcpy(*tl_copy, tl_bh->b_data, tl_bh->b_size);
|
||||
|
||||
/* All we need to do to clear the truncate log is set
|
||||
* tl_used. */
|
||||
tl->tl_used = 0;
|
||||
|
@@ -242,57 +242,29 @@ static struct dentry *blockcheck_debugfs_create(const char *name,
|
||||
static void ocfs2_blockcheck_debug_remove(struct ocfs2_blockcheck_stats *stats)
|
||||
{
|
||||
if (stats) {
|
||||
debugfs_remove(stats->b_debug_check);
|
||||
stats->b_debug_check = NULL;
|
||||
debugfs_remove(stats->b_debug_failure);
|
||||
stats->b_debug_failure = NULL;
|
||||
debugfs_remove(stats->b_debug_recover);
|
||||
stats->b_debug_recover = NULL;
|
||||
debugfs_remove(stats->b_debug_dir);
|
||||
debugfs_remove_recursive(stats->b_debug_dir);
|
||||
stats->b_debug_dir = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int ocfs2_blockcheck_debug_install(struct ocfs2_blockcheck_stats *stats,
|
||||
struct dentry *parent)
|
||||
static void ocfs2_blockcheck_debug_install(struct ocfs2_blockcheck_stats *stats,
|
||||
struct dentry *parent)
|
||||
{
|
||||
int rc = -EINVAL;
|
||||
|
||||
if (!stats)
|
||||
goto out;
|
||||
|
||||
stats->b_debug_dir = debugfs_create_dir("blockcheck", parent);
|
||||
if (!stats->b_debug_dir)
|
||||
goto out;
|
||||
|
||||
stats->b_debug_check =
|
||||
blockcheck_debugfs_create("blocks_checked",
|
||||
stats->b_debug_dir,
|
||||
&stats->b_check_count);
|
||||
blockcheck_debugfs_create("blocks_checked", stats->b_debug_dir,
|
||||
&stats->b_check_count);
|
||||
|
||||
stats->b_debug_failure =
|
||||
blockcheck_debugfs_create("checksums_failed",
|
||||
stats->b_debug_dir,
|
||||
&stats->b_failure_count);
|
||||
blockcheck_debugfs_create("checksums_failed", stats->b_debug_dir,
|
||||
&stats->b_failure_count);
|
||||
|
||||
stats->b_debug_recover =
|
||||
blockcheck_debugfs_create("ecc_recoveries",
|
||||
stats->b_debug_dir,
|
||||
&stats->b_recover_count);
|
||||
if (stats->b_debug_check && stats->b_debug_failure &&
|
||||
stats->b_debug_recover)
|
||||
rc = 0;
|
||||
|
||||
out:
|
||||
if (rc)
|
||||
ocfs2_blockcheck_debug_remove(stats);
|
||||
return rc;
|
||||
blockcheck_debugfs_create("ecc_recoveries", stats->b_debug_dir,
|
||||
&stats->b_recover_count);
|
||||
}
|
||||
#else
|
||||
static inline int ocfs2_blockcheck_debug_install(struct ocfs2_blockcheck_stats *stats,
|
||||
struct dentry *parent)
|
||||
static inline void ocfs2_blockcheck_debug_install(struct ocfs2_blockcheck_stats *stats,
|
||||
struct dentry *parent)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void ocfs2_blockcheck_debug_remove(struct ocfs2_blockcheck_stats *stats)
|
||||
@@ -301,10 +273,10 @@ static inline void ocfs2_blockcheck_debug_remove(struct ocfs2_blockcheck_stats *
|
||||
#endif /* CONFIG_DEBUG_FS */
|
||||
|
||||
/* Always-called wrappers for starting and stopping the debugfs files */
|
||||
int ocfs2_blockcheck_stats_debugfs_install(struct ocfs2_blockcheck_stats *stats,
|
||||
struct dentry *parent)
|
||||
void ocfs2_blockcheck_stats_debugfs_install(struct ocfs2_blockcheck_stats *stats,
|
||||
struct dentry *parent)
|
||||
{
|
||||
return ocfs2_blockcheck_debug_install(stats, parent);
|
||||
ocfs2_blockcheck_debug_install(stats, parent);
|
||||
}
|
||||
|
||||
void ocfs2_blockcheck_stats_debugfs_remove(struct ocfs2_blockcheck_stats *stats)
|
||||
|
@@ -25,9 +25,6 @@ struct ocfs2_blockcheck_stats {
|
||||
* ocfs2_blockcheck_stats_debugfs_install()
|
||||
*/
|
||||
struct dentry *b_debug_dir; /* Parent of the debugfs files */
|
||||
struct dentry *b_debug_check; /* Exposes b_check_count */
|
||||
struct dentry *b_debug_failure; /* Exposes b_failure_count */
|
||||
struct dentry *b_debug_recover; /* Exposes b_recover_count */
|
||||
};
|
||||
|
||||
|
||||
@@ -56,8 +53,8 @@ int ocfs2_block_check_validate_bhs(struct buffer_head **bhs, int nr,
|
||||
struct ocfs2_blockcheck_stats *stats);
|
||||
|
||||
/* Debug Initialization */
|
||||
int ocfs2_blockcheck_stats_debugfs_install(struct ocfs2_blockcheck_stats *stats,
|
||||
struct dentry *parent);
|
||||
void ocfs2_blockcheck_stats_debugfs_install(struct ocfs2_blockcheck_stats *stats,
|
||||
struct dentry *parent);
|
||||
void ocfs2_blockcheck_stats_debugfs_remove(struct ocfs2_blockcheck_stats *stats);
|
||||
|
||||
/*
|
||||
|
@@ -92,10 +92,6 @@ static struct o2hb_debug_buf *o2hb_db_failedregions;
|
||||
#define O2HB_DEBUG_REGION_PINNED "pinned"
|
||||
|
||||
static struct dentry *o2hb_debug_dir;
|
||||
static struct dentry *o2hb_debug_livenodes;
|
||||
static struct dentry *o2hb_debug_liveregions;
|
||||
static struct dentry *o2hb_debug_quorumregions;
|
||||
static struct dentry *o2hb_debug_failedregions;
|
||||
|
||||
static LIST_HEAD(o2hb_all_regions);
|
||||
|
||||
@@ -1184,7 +1180,7 @@ bail:
|
||||
if (atomic_read(®->hr_steady_iterations) != 0) {
|
||||
if (atomic_dec_and_test(®->hr_unsteady_iterations)) {
|
||||
printk(KERN_NOTICE "o2hb: Unable to stabilize "
|
||||
"heartbeart on region %s (%s)\n",
|
||||
"heartbeat on region %s (%s)\n",
|
||||
config_item_name(®->hr_item),
|
||||
reg->hr_dev_name);
|
||||
atomic_set(®->hr_steady_iterations, 0);
|
||||
@@ -1391,11 +1387,7 @@ static const struct file_operations o2hb_debug_fops = {
|
||||
|
||||
void o2hb_exit(void)
|
||||
{
|
||||
debugfs_remove(o2hb_debug_failedregions);
|
||||
debugfs_remove(o2hb_debug_quorumregions);
|
||||
debugfs_remove(o2hb_debug_liveregions);
|
||||
debugfs_remove(o2hb_debug_livenodes);
|
||||
debugfs_remove(o2hb_debug_dir);
|
||||
debugfs_remove_recursive(o2hb_debug_dir);
|
||||
kfree(o2hb_db_livenodes);
|
||||
kfree(o2hb_db_liveregions);
|
||||
kfree(o2hb_db_quorumregions);
|
||||
@@ -1419,79 +1411,37 @@ static struct dentry *o2hb_debug_create(const char *name, struct dentry *dir,
|
||||
&o2hb_debug_fops);
|
||||
}
|
||||
|
||||
static int o2hb_debug_init(void)
|
||||
static void o2hb_debug_init(void)
|
||||
{
|
||||
int ret = -ENOMEM;
|
||||
|
||||
o2hb_debug_dir = debugfs_create_dir(O2HB_DEBUG_DIR, NULL);
|
||||
if (!o2hb_debug_dir) {
|
||||
mlog_errno(ret);
|
||||
goto bail;
|
||||
}
|
||||
|
||||
o2hb_debug_livenodes = o2hb_debug_create(O2HB_DEBUG_LIVENODES,
|
||||
o2hb_debug_dir,
|
||||
&o2hb_db_livenodes,
|
||||
sizeof(*o2hb_db_livenodes),
|
||||
O2HB_DB_TYPE_LIVENODES,
|
||||
sizeof(o2hb_live_node_bitmap),
|
||||
O2NM_MAX_NODES,
|
||||
o2hb_live_node_bitmap);
|
||||
if (!o2hb_debug_livenodes) {
|
||||
mlog_errno(ret);
|
||||
goto bail;
|
||||
}
|
||||
o2hb_debug_create(O2HB_DEBUG_LIVENODES, o2hb_debug_dir,
|
||||
&o2hb_db_livenodes, sizeof(*o2hb_db_livenodes),
|
||||
O2HB_DB_TYPE_LIVENODES, sizeof(o2hb_live_node_bitmap),
|
||||
O2NM_MAX_NODES, o2hb_live_node_bitmap);
|
||||
|
||||
o2hb_debug_liveregions = o2hb_debug_create(O2HB_DEBUG_LIVEREGIONS,
|
||||
o2hb_debug_dir,
|
||||
&o2hb_db_liveregions,
|
||||
sizeof(*o2hb_db_liveregions),
|
||||
O2HB_DB_TYPE_LIVEREGIONS,
|
||||
sizeof(o2hb_live_region_bitmap),
|
||||
O2NM_MAX_REGIONS,
|
||||
o2hb_live_region_bitmap);
|
||||
if (!o2hb_debug_liveregions) {
|
||||
mlog_errno(ret);
|
||||
goto bail;
|
||||
}
|
||||
o2hb_debug_create(O2HB_DEBUG_LIVEREGIONS, o2hb_debug_dir,
|
||||
&o2hb_db_liveregions, sizeof(*o2hb_db_liveregions),
|
||||
O2HB_DB_TYPE_LIVEREGIONS,
|
||||
sizeof(o2hb_live_region_bitmap), O2NM_MAX_REGIONS,
|
||||
o2hb_live_region_bitmap);
|
||||
|
||||
o2hb_debug_quorumregions =
|
||||
o2hb_debug_create(O2HB_DEBUG_QUORUMREGIONS,
|
||||
o2hb_debug_dir,
|
||||
&o2hb_db_quorumregions,
|
||||
sizeof(*o2hb_db_quorumregions),
|
||||
O2HB_DB_TYPE_QUORUMREGIONS,
|
||||
sizeof(o2hb_quorum_region_bitmap),
|
||||
O2NM_MAX_REGIONS,
|
||||
o2hb_quorum_region_bitmap);
|
||||
if (!o2hb_debug_quorumregions) {
|
||||
mlog_errno(ret);
|
||||
goto bail;
|
||||
}
|
||||
o2hb_debug_create(O2HB_DEBUG_QUORUMREGIONS, o2hb_debug_dir,
|
||||
&o2hb_db_quorumregions,
|
||||
sizeof(*o2hb_db_quorumregions),
|
||||
O2HB_DB_TYPE_QUORUMREGIONS,
|
||||
sizeof(o2hb_quorum_region_bitmap), O2NM_MAX_REGIONS,
|
||||
o2hb_quorum_region_bitmap);
|
||||
|
||||
o2hb_debug_failedregions =
|
||||
o2hb_debug_create(O2HB_DEBUG_FAILEDREGIONS,
|
||||
o2hb_debug_dir,
|
||||
&o2hb_db_failedregions,
|
||||
sizeof(*o2hb_db_failedregions),
|
||||
O2HB_DB_TYPE_FAILEDREGIONS,
|
||||
sizeof(o2hb_failed_region_bitmap),
|
||||
O2NM_MAX_REGIONS,
|
||||
o2hb_failed_region_bitmap);
|
||||
if (!o2hb_debug_failedregions) {
|
||||
mlog_errno(ret);
|
||||
goto bail;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
bail:
|
||||
if (ret)
|
||||
o2hb_exit();
|
||||
|
||||
return ret;
|
||||
o2hb_debug_create(O2HB_DEBUG_FAILEDREGIONS, o2hb_debug_dir,
|
||||
&o2hb_db_failedregions,
|
||||
sizeof(*o2hb_db_failedregions),
|
||||
O2HB_DB_TYPE_FAILEDREGIONS,
|
||||
sizeof(o2hb_failed_region_bitmap), O2NM_MAX_REGIONS,
|
||||
o2hb_failed_region_bitmap);
|
||||
}
|
||||
|
||||
int o2hb_init(void)
|
||||
void o2hb_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -1511,7 +1461,7 @@ int o2hb_init(void)
|
||||
|
||||
o2hb_dependent_users = 0;
|
||||
|
||||
return o2hb_debug_init();
|
||||
o2hb_debug_init();
|
||||
}
|
||||
|
||||
/* if we're already in a callback then we're already serialized by the sem */
|
||||
|
@@ -63,7 +63,7 @@ void o2hb_unregister_callback(const char *region_uuid,
|
||||
void o2hb_fill_node_map(unsigned long *map,
|
||||
unsigned bytes);
|
||||
void o2hb_exit(void);
|
||||
int o2hb_init(void);
|
||||
void o2hb_init(void);
|
||||
int o2hb_check_node_heartbeating_no_sem(u8 node_num);
|
||||
int o2hb_check_node_heartbeating_from_callback(u8 node_num);
|
||||
void o2hb_stop_all_regions(void);
|
||||
|
@@ -38,10 +38,6 @@
|
||||
#define SHOW_SOCK_STATS 1
|
||||
|
||||
static struct dentry *o2net_dentry;
|
||||
static struct dentry *sc_dentry;
|
||||
static struct dentry *nst_dentry;
|
||||
static struct dentry *stats_dentry;
|
||||
static struct dentry *nodes_dentry;
|
||||
|
||||
static DEFINE_SPINLOCK(o2net_debug_lock);
|
||||
|
||||
@@ -490,36 +486,23 @@ static const struct file_operations nodes_fops = {
|
||||
|
||||
void o2net_debugfs_exit(void)
|
||||
{
|
||||
debugfs_remove(nodes_dentry);
|
||||
debugfs_remove(stats_dentry);
|
||||
debugfs_remove(sc_dentry);
|
||||
debugfs_remove(nst_dentry);
|
||||
debugfs_remove(o2net_dentry);
|
||||
debugfs_remove_recursive(o2net_dentry);
|
||||
}
|
||||
|
||||
int o2net_debugfs_init(void)
|
||||
void o2net_debugfs_init(void)
|
||||
{
|
||||
umode_t mode = S_IFREG|S_IRUSR;
|
||||
|
||||
o2net_dentry = debugfs_create_dir(O2NET_DEBUG_DIR, NULL);
|
||||
if (o2net_dentry)
|
||||
nst_dentry = debugfs_create_file(NST_DEBUG_NAME, mode,
|
||||
o2net_dentry, NULL, &nst_seq_fops);
|
||||
if (nst_dentry)
|
||||
sc_dentry = debugfs_create_file(SC_DEBUG_NAME, mode,
|
||||
o2net_dentry, NULL, &sc_seq_fops);
|
||||
if (sc_dentry)
|
||||
stats_dentry = debugfs_create_file(STATS_DEBUG_NAME, mode,
|
||||
o2net_dentry, NULL, &stats_seq_fops);
|
||||
if (stats_dentry)
|
||||
nodes_dentry = debugfs_create_file(NODES_DEBUG_NAME, mode,
|
||||
o2net_dentry, NULL, &nodes_fops);
|
||||
if (nodes_dentry)
|
||||
return 0;
|
||||
|
||||
o2net_debugfs_exit();
|
||||
mlog_errno(-ENOMEM);
|
||||
return -ENOMEM;
|
||||
debugfs_create_file(NST_DEBUG_NAME, mode, o2net_dentry, NULL,
|
||||
&nst_seq_fops);
|
||||
debugfs_create_file(SC_DEBUG_NAME, mode, o2net_dentry, NULL,
|
||||
&sc_seq_fops);
|
||||
debugfs_create_file(STATS_DEBUG_NAME, mode, o2net_dentry, NULL,
|
||||
&stats_seq_fops);
|
||||
debugfs_create_file(NODES_DEBUG_NAME, mode, o2net_dentry, NULL,
|
||||
&nodes_fops);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_DEBUG_FS */
|
||||
|
@@ -828,9 +828,7 @@ static int __init init_o2nm(void)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
ret = o2hb_init();
|
||||
if (ret)
|
||||
goto out;
|
||||
o2hb_init();
|
||||
|
||||
ret = o2net_init();
|
||||
if (ret)
|
||||
|
@@ -76,7 +76,7 @@ static void o2quo_fence_self(void)
|
||||
};
|
||||
}
|
||||
|
||||
/* Indicate that a timeout occurred on a hearbeat region write. The
|
||||
/* Indicate that a timeout occurred on a heartbeat region write. The
|
||||
* other nodes in the cluster may consider us dead at that time so we
|
||||
* want to "fence" ourselves so that we don't scribble on the disk
|
||||
* after they think they've recovered us. This can't solve all
|
||||
|
@@ -1762,7 +1762,7 @@ static void o2net_hb_node_up_cb(struct o2nm_node *node, int node_num,
|
||||
(msecs_to_jiffies(o2net_reconnect_delay()) + 1);
|
||||
|
||||
if (node_num != o2nm_this_node()) {
|
||||
/* believe it or not, accept and node hearbeating testing
|
||||
/* believe it or not, accept and node heartbeating testing
|
||||
* can succeed for this node before we got here.. so
|
||||
* only use set_nn_state to clear the persistent error
|
||||
* if that hasn't already happened */
|
||||
@@ -2129,8 +2129,7 @@ int o2net_init(void)
|
||||
|
||||
o2quo_init();
|
||||
|
||||
if (o2net_debugfs_init())
|
||||
goto out;
|
||||
o2net_debugfs_init();
|
||||
|
||||
o2net_hand = kzalloc(sizeof(struct o2net_handshake), GFP_KERNEL);
|
||||
o2net_keep_req = kzalloc(sizeof(struct o2net_msg), GFP_KERNEL);
|
||||
|
@@ -109,16 +109,15 @@ struct o2net_send_tracking;
|
||||
struct o2net_sock_container;
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
int o2net_debugfs_init(void);
|
||||
void o2net_debugfs_init(void);
|
||||
void o2net_debugfs_exit(void);
|
||||
void o2net_debug_add_nst(struct o2net_send_tracking *nst);
|
||||
void o2net_debug_del_nst(struct o2net_send_tracking *nst);
|
||||
void o2net_debug_add_sc(struct o2net_sock_container *sc);
|
||||
void o2net_debug_del_sc(struct o2net_sock_container *sc);
|
||||
#else
|
||||
static inline int o2net_debugfs_init(void)
|
||||
static inline void o2net_debugfs_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline void o2net_debugfs_exit(void)
|
||||
{
|
||||
|
@@ -851,7 +851,7 @@ static const struct file_operations debug_state_fops = {
|
||||
/* end - debug state funcs */
|
||||
|
||||
/* files in subroot */
|
||||
int dlm_debug_init(struct dlm_ctxt *dlm)
|
||||
void dlm_debug_init(struct dlm_ctxt *dlm)
|
||||
{
|
||||
struct dlm_debug_ctxt *dc = dlm->dlm_debug_ctxt;
|
||||
|
||||
@@ -860,10 +860,6 @@ int dlm_debug_init(struct dlm_ctxt *dlm)
|
||||
S_IFREG|S_IRUSR,
|
||||
dlm->dlm_debugfs_subroot,
|
||||
dlm, &debug_state_fops);
|
||||
if (!dc->debug_state_dentry) {
|
||||
mlog_errno(-ENOMEM);
|
||||
goto bail;
|
||||
}
|
||||
|
||||
/* for dumping lockres */
|
||||
dc->debug_lockres_dentry =
|
||||
@@ -871,20 +867,12 @@ int dlm_debug_init(struct dlm_ctxt *dlm)
|
||||
S_IFREG|S_IRUSR,
|
||||
dlm->dlm_debugfs_subroot,
|
||||
dlm, &debug_lockres_fops);
|
||||
if (!dc->debug_lockres_dentry) {
|
||||
mlog_errno(-ENOMEM);
|
||||
goto bail;
|
||||
}
|
||||
|
||||
/* for dumping mles */
|
||||
dc->debug_mle_dentry = debugfs_create_file(DLM_DEBUGFS_MLE_STATE,
|
||||
S_IFREG|S_IRUSR,
|
||||
dlm->dlm_debugfs_subroot,
|
||||
dlm, &debug_mle_fops);
|
||||
if (!dc->debug_mle_dentry) {
|
||||
mlog_errno(-ENOMEM);
|
||||
goto bail;
|
||||
}
|
||||
|
||||
/* for dumping lockres on the purge list */
|
||||
dc->debug_purgelist_dentry =
|
||||
@@ -892,15 +880,6 @@ int dlm_debug_init(struct dlm_ctxt *dlm)
|
||||
S_IFREG|S_IRUSR,
|
||||
dlm->dlm_debugfs_subroot,
|
||||
dlm, &debug_purgelist_fops);
|
||||
if (!dc->debug_purgelist_dentry) {
|
||||
mlog_errno(-ENOMEM);
|
||||
goto bail;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
bail:
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
void dlm_debug_shutdown(struct dlm_ctxt *dlm)
|
||||
@@ -920,24 +899,16 @@ void dlm_debug_shutdown(struct dlm_ctxt *dlm)
|
||||
/* subroot - domain dir */
|
||||
int dlm_create_debugfs_subroot(struct dlm_ctxt *dlm)
|
||||
{
|
||||
dlm->dlm_debugfs_subroot = debugfs_create_dir(dlm->name,
|
||||
dlm_debugfs_root);
|
||||
if (!dlm->dlm_debugfs_subroot) {
|
||||
mlog_errno(-ENOMEM);
|
||||
goto bail;
|
||||
}
|
||||
|
||||
dlm->dlm_debug_ctxt = kzalloc(sizeof(struct dlm_debug_ctxt),
|
||||
GFP_KERNEL);
|
||||
if (!dlm->dlm_debug_ctxt) {
|
||||
mlog_errno(-ENOMEM);
|
||||
goto bail;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
dlm->dlm_debugfs_subroot = debugfs_create_dir(dlm->name,
|
||||
dlm_debugfs_root);
|
||||
return 0;
|
||||
bail:
|
||||
dlm_destroy_debugfs_subroot(dlm);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
void dlm_destroy_debugfs_subroot(struct dlm_ctxt *dlm)
|
||||
@@ -946,14 +917,9 @@ void dlm_destroy_debugfs_subroot(struct dlm_ctxt *dlm)
|
||||
}
|
||||
|
||||
/* debugfs root */
|
||||
int dlm_create_debugfs_root(void)
|
||||
void dlm_create_debugfs_root(void)
|
||||
{
|
||||
dlm_debugfs_root = debugfs_create_dir(DLM_DEBUGFS_DIR, NULL);
|
||||
if (!dlm_debugfs_root) {
|
||||
mlog_errno(-ENOMEM);
|
||||
return -ENOMEM;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void dlm_destroy_debugfs_root(void)
|
||||
|
@@ -28,20 +28,19 @@ struct debug_lockres {
|
||||
struct dlm_lock_resource *dl_res;
|
||||
};
|
||||
|
||||
int dlm_debug_init(struct dlm_ctxt *dlm);
|
||||
void dlm_debug_init(struct dlm_ctxt *dlm);
|
||||
void dlm_debug_shutdown(struct dlm_ctxt *dlm);
|
||||
|
||||
int dlm_create_debugfs_subroot(struct dlm_ctxt *dlm);
|
||||
void dlm_destroy_debugfs_subroot(struct dlm_ctxt *dlm);
|
||||
|
||||
int dlm_create_debugfs_root(void);
|
||||
void dlm_create_debugfs_root(void);
|
||||
void dlm_destroy_debugfs_root(void);
|
||||
|
||||
#else
|
||||
|
||||
static inline int dlm_debug_init(struct dlm_ctxt *dlm)
|
||||
static inline void dlm_debug_init(struct dlm_ctxt *dlm)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline void dlm_debug_shutdown(struct dlm_ctxt *dlm)
|
||||
{
|
||||
@@ -53,9 +52,8 @@ static inline int dlm_create_debugfs_subroot(struct dlm_ctxt *dlm)
|
||||
static inline void dlm_destroy_debugfs_subroot(struct dlm_ctxt *dlm)
|
||||
{
|
||||
}
|
||||
static inline int dlm_create_debugfs_root(void)
|
||||
static inline void dlm_create_debugfs_root(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline void dlm_destroy_debugfs_root(void)
|
||||
{
|
||||
|
@@ -1881,11 +1881,7 @@ static int dlm_join_domain(struct dlm_ctxt *dlm)
|
||||
goto bail;
|
||||
}
|
||||
|
||||
status = dlm_debug_init(dlm);
|
||||
if (status < 0) {
|
||||
mlog_errno(status);
|
||||
goto bail;
|
||||
}
|
||||
dlm_debug_init(dlm);
|
||||
|
||||
snprintf(wq_name, O2NM_MAX_NAME_LEN, "dlm_wq-%s", dlm->name);
|
||||
dlm->dlm_worker = alloc_workqueue(wq_name, WQ_MEM_RECLAIM, 0);
|
||||
@@ -2346,9 +2342,7 @@ static int __init dlm_init(void)
|
||||
goto error;
|
||||
}
|
||||
|
||||
status = dlm_create_debugfs_root();
|
||||
if (status)
|
||||
goto error;
|
||||
dlm_create_debugfs_root();
|
||||
|
||||
return 0;
|
||||
error:
|
||||
|
@@ -2161,7 +2161,7 @@ put:
|
||||
* think that $RECOVERY is currently mastered by a dead node. If so,
|
||||
* we wait a short time to allow that node to get notified by its own
|
||||
* heartbeat stack, then check again. All $RECOVERY lock resources
|
||||
* mastered by dead nodes are purged when the hearbeat callback is
|
||||
* mastered by dead nodes are purged when the heartbeat callback is
|
||||
* fired, so we can know for sure that it is safe to continue once
|
||||
* the node returns a live node or no node. */
|
||||
static int dlm_pre_master_reco_lockres(struct dlm_ctxt *dlm,
|
||||
|
@@ -1109,7 +1109,7 @@ static int dlm_send_mig_lockres_msg(struct dlm_ctxt *dlm,
|
||||
{
|
||||
u64 mig_cookie = be64_to_cpu(mres->mig_cookie);
|
||||
int mres_total_locks = be32_to_cpu(mres->total_locks);
|
||||
int sz, ret = 0, status = 0;
|
||||
int ret = 0, status = 0;
|
||||
u8 orig_flags = mres->flags,
|
||||
orig_master = mres->master;
|
||||
|
||||
@@ -1117,9 +1117,6 @@ static int dlm_send_mig_lockres_msg(struct dlm_ctxt *dlm,
|
||||
if (!mres->num_locks)
|
||||
return 0;
|
||||
|
||||
sz = sizeof(struct dlm_migratable_lockres) +
|
||||
(mres->num_locks * sizeof(struct dlm_migratable_lock));
|
||||
|
||||
/* add an all-done flag if we reached the last lock */
|
||||
orig_flags = mres->flags;
|
||||
BUG_ON(total_locks > mres_total_locks);
|
||||
@@ -1133,7 +1130,8 @@ static int dlm_send_mig_lockres_msg(struct dlm_ctxt *dlm,
|
||||
|
||||
/* send it */
|
||||
ret = o2net_send_message(DLM_MIG_LOCKRES_MSG, dlm->key, mres,
|
||||
sz, send_to, &status);
|
||||
struct_size(mres, ml, mres->num_locks),
|
||||
send_to, &status);
|
||||
if (ret < 0) {
|
||||
/* XXX: negative status is not handled.
|
||||
* this will end up killing this node. */
|
||||
|
@@ -426,6 +426,7 @@ static void ocfs2_remove_lockres_tracking(struct ocfs2_lock_res *res)
|
||||
static void ocfs2_init_lock_stats(struct ocfs2_lock_res *res)
|
||||
{
|
||||
res->l_lock_refresh = 0;
|
||||
res->l_lock_wait = 0;
|
||||
memset(&res->l_lock_prmode, 0, sizeof(struct ocfs2_lock_stats));
|
||||
memset(&res->l_lock_exmode, 0, sizeof(struct ocfs2_lock_stats));
|
||||
}
|
||||
@@ -460,6 +461,8 @@ static void ocfs2_update_lock_stats(struct ocfs2_lock_res *res, int level,
|
||||
|
||||
if (ret)
|
||||
stats->ls_fail++;
|
||||
|
||||
stats->ls_last = ktime_to_us(ktime_get_real());
|
||||
}
|
||||
|
||||
static inline void ocfs2_track_lock_refresh(struct ocfs2_lock_res *lockres)
|
||||
@@ -467,6 +470,21 @@ static inline void ocfs2_track_lock_refresh(struct ocfs2_lock_res *lockres)
|
||||
lockres->l_lock_refresh++;
|
||||
}
|
||||
|
||||
static inline void ocfs2_track_lock_wait(struct ocfs2_lock_res *lockres)
|
||||
{
|
||||
struct ocfs2_mask_waiter *mw;
|
||||
|
||||
if (list_empty(&lockres->l_mask_waiters)) {
|
||||
lockres->l_lock_wait = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
mw = list_first_entry(&lockres->l_mask_waiters,
|
||||
struct ocfs2_mask_waiter, mw_item);
|
||||
lockres->l_lock_wait =
|
||||
ktime_to_us(ktime_mono_to_real(mw->mw_lock_start));
|
||||
}
|
||||
|
||||
static inline void ocfs2_init_start_time(struct ocfs2_mask_waiter *mw)
|
||||
{
|
||||
mw->mw_lock_start = ktime_get();
|
||||
@@ -482,6 +500,9 @@ static inline void ocfs2_update_lock_stats(struct ocfs2_lock_res *res,
|
||||
static inline void ocfs2_track_lock_refresh(struct ocfs2_lock_res *lockres)
|
||||
{
|
||||
}
|
||||
static inline void ocfs2_track_lock_wait(struct ocfs2_lock_res *lockres)
|
||||
{
|
||||
}
|
||||
static inline void ocfs2_init_start_time(struct ocfs2_mask_waiter *mw)
|
||||
{
|
||||
}
|
||||
@@ -875,6 +896,7 @@ static void lockres_set_flags(struct ocfs2_lock_res *lockres,
|
||||
list_del_init(&mw->mw_item);
|
||||
mw->mw_status = 0;
|
||||
complete(&mw->mw_complete);
|
||||
ocfs2_track_lock_wait(lockres);
|
||||
}
|
||||
}
|
||||
static void lockres_or_flags(struct ocfs2_lock_res *lockres, unsigned long or)
|
||||
@@ -1386,6 +1408,7 @@ static void lockres_add_mask_waiter(struct ocfs2_lock_res *lockres,
|
||||
list_add_tail(&mw->mw_item, &lockres->l_mask_waiters);
|
||||
mw->mw_mask = mask;
|
||||
mw->mw_goal = goal;
|
||||
ocfs2_track_lock_wait(lockres);
|
||||
}
|
||||
|
||||
/* returns 0 if the mw that was removed was already satisfied, -EBUSY
|
||||
@@ -1402,6 +1425,7 @@ static int __lockres_remove_mask_waiter(struct ocfs2_lock_res *lockres,
|
||||
|
||||
list_del_init(&mw->mw_item);
|
||||
init_completion(&mw->mw_complete);
|
||||
ocfs2_track_lock_wait(lockres);
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -2989,6 +3013,8 @@ struct ocfs2_dlm_debug *ocfs2_new_dlm_debug(void)
|
||||
kref_init(&dlm_debug->d_refcnt);
|
||||
INIT_LIST_HEAD(&dlm_debug->d_lockres_tracking);
|
||||
dlm_debug->d_locking_state = NULL;
|
||||
dlm_debug->d_locking_filter = NULL;
|
||||
dlm_debug->d_filter_secs = 0;
|
||||
out:
|
||||
return dlm_debug;
|
||||
}
|
||||
@@ -3079,17 +3105,43 @@ static void *ocfs2_dlm_seq_next(struct seq_file *m, void *v, loff_t *pos)
|
||||
* - Lock stats printed
|
||||
* New in version 3
|
||||
* - Max time in lock stats is in usecs (instead of nsecs)
|
||||
* New in version 4
|
||||
* - Add last pr/ex unlock times and first lock wait time in usecs
|
||||
*/
|
||||
#define OCFS2_DLM_DEBUG_STR_VERSION 3
|
||||
#define OCFS2_DLM_DEBUG_STR_VERSION 4
|
||||
static int ocfs2_dlm_seq_show(struct seq_file *m, void *v)
|
||||
{
|
||||
int i;
|
||||
char *lvb;
|
||||
struct ocfs2_lock_res *lockres = v;
|
||||
#ifdef CONFIG_OCFS2_FS_STATS
|
||||
u64 now, last;
|
||||
struct ocfs2_dlm_debug *dlm_debug =
|
||||
((struct ocfs2_dlm_seq_priv *)m->private)->p_dlm_debug;
|
||||
#endif
|
||||
|
||||
if (!lockres)
|
||||
return -EINVAL;
|
||||
|
||||
#ifdef CONFIG_OCFS2_FS_STATS
|
||||
if (!lockres->l_lock_wait && dlm_debug->d_filter_secs) {
|
||||
now = ktime_to_us(ktime_get_real());
|
||||
if (lockres->l_lock_prmode.ls_last >
|
||||
lockres->l_lock_exmode.ls_last)
|
||||
last = lockres->l_lock_prmode.ls_last;
|
||||
else
|
||||
last = lockres->l_lock_exmode.ls_last;
|
||||
/*
|
||||
* Use d_filter_secs field to filter lock resources dump,
|
||||
* the default d_filter_secs(0) value filters nothing,
|
||||
* otherwise, only dump the last N seconds active lock
|
||||
* resources.
|
||||
*/
|
||||
if (div_u64(now - last, 1000000) > dlm_debug->d_filter_secs)
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
seq_printf(m, "0x%x\t", OCFS2_DLM_DEBUG_STR_VERSION);
|
||||
|
||||
if (lockres->l_type == OCFS2_LOCK_TYPE_DENTRY)
|
||||
@@ -3131,6 +3183,9 @@ static int ocfs2_dlm_seq_show(struct seq_file *m, void *v)
|
||||
# define lock_max_prmode(_l) ((_l)->l_lock_prmode.ls_max)
|
||||
# define lock_max_exmode(_l) ((_l)->l_lock_exmode.ls_max)
|
||||
# define lock_refresh(_l) ((_l)->l_lock_refresh)
|
||||
# define lock_last_prmode(_l) ((_l)->l_lock_prmode.ls_last)
|
||||
# define lock_last_exmode(_l) ((_l)->l_lock_exmode.ls_last)
|
||||
# define lock_wait(_l) ((_l)->l_lock_wait)
|
||||
#else
|
||||
# define lock_num_prmode(_l) (0)
|
||||
# define lock_num_exmode(_l) (0)
|
||||
@@ -3141,6 +3196,9 @@ static int ocfs2_dlm_seq_show(struct seq_file *m, void *v)
|
||||
# define lock_max_prmode(_l) (0)
|
||||
# define lock_max_exmode(_l) (0)
|
||||
# define lock_refresh(_l) (0)
|
||||
# define lock_last_prmode(_l) (0ULL)
|
||||
# define lock_last_exmode(_l) (0ULL)
|
||||
# define lock_wait(_l) (0ULL)
|
||||
#endif
|
||||
/* The following seq_print was added in version 2 of this output */
|
||||
seq_printf(m, "%u\t"
|
||||
@@ -3151,7 +3209,10 @@ static int ocfs2_dlm_seq_show(struct seq_file *m, void *v)
|
||||
"%llu\t"
|
||||
"%u\t"
|
||||
"%u\t"
|
||||
"%u\t",
|
||||
"%u\t"
|
||||
"%llu\t"
|
||||
"%llu\t"
|
||||
"%llu\t",
|
||||
lock_num_prmode(lockres),
|
||||
lock_num_exmode(lockres),
|
||||
lock_num_prmode_failed(lockres),
|
||||
@@ -3160,7 +3221,10 @@ static int ocfs2_dlm_seq_show(struct seq_file *m, void *v)
|
||||
lock_total_exmode(lockres),
|
||||
lock_max_prmode(lockres),
|
||||
lock_max_exmode(lockres),
|
||||
lock_refresh(lockres));
|
||||
lock_refresh(lockres),
|
||||
lock_last_prmode(lockres),
|
||||
lock_last_exmode(lockres),
|
||||
lock_wait(lockres));
|
||||
|
||||
/* End the line */
|
||||
seq_printf(m, "\n");
|
||||
@@ -3214,9 +3278,8 @@ static const struct file_operations ocfs2_dlm_debug_fops = {
|
||||
.llseek = seq_lseek,
|
||||
};
|
||||
|
||||
static int ocfs2_dlm_init_debug(struct ocfs2_super *osb)
|
||||
static void ocfs2_dlm_init_debug(struct ocfs2_super *osb)
|
||||
{
|
||||
int ret = 0;
|
||||
struct ocfs2_dlm_debug *dlm_debug = osb->osb_dlm_debug;
|
||||
|
||||
dlm_debug->d_locking_state = debugfs_create_file("locking_state",
|
||||
@@ -3224,16 +3287,11 @@ static int ocfs2_dlm_init_debug(struct ocfs2_super *osb)
|
||||
osb->osb_debug_root,
|
||||
osb,
|
||||
&ocfs2_dlm_debug_fops);
|
||||
if (!dlm_debug->d_locking_state) {
|
||||
ret = -EINVAL;
|
||||
mlog(ML_ERROR,
|
||||
"Unable to create locking state debugfs file.\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
ocfs2_get_dlm_debug(dlm_debug);
|
||||
out:
|
||||
return ret;
|
||||
dlm_debug->d_locking_filter = debugfs_create_u32("locking_filter",
|
||||
0600,
|
||||
osb->osb_debug_root,
|
||||
&dlm_debug->d_filter_secs);
|
||||
}
|
||||
|
||||
static void ocfs2_dlm_shutdown_debug(struct ocfs2_super *osb)
|
||||
@@ -3242,6 +3300,7 @@ static void ocfs2_dlm_shutdown_debug(struct ocfs2_super *osb)
|
||||
|
||||
if (dlm_debug) {
|
||||
debugfs_remove(dlm_debug->d_locking_state);
|
||||
debugfs_remove(dlm_debug->d_locking_filter);
|
||||
ocfs2_put_dlm_debug(dlm_debug);
|
||||
}
|
||||
}
|
||||
@@ -3256,11 +3315,7 @@ int ocfs2_dlm_init(struct ocfs2_super *osb)
|
||||
goto local;
|
||||
}
|
||||
|
||||
status = ocfs2_dlm_init_debug(osb);
|
||||
if (status < 0) {
|
||||
mlog_errno(status);
|
||||
goto bail;
|
||||
}
|
||||
ocfs2_dlm_init_debug(osb);
|
||||
|
||||
/* launch downconvert thread */
|
||||
osb->dc_task = kthread_run(ocfs2_downconvert_thread, osb, "ocfs2dc-%s",
|
||||
@@ -4352,7 +4407,6 @@ static int ocfs2_downconvert_thread_should_wake(struct ocfs2_super *osb)
|
||||
|
||||
static int ocfs2_downconvert_thread(void *arg)
|
||||
{
|
||||
int status = 0;
|
||||
struct ocfs2_super *osb = arg;
|
||||
|
||||
/* only quit once we've been asked to stop and there is no more
|
||||
@@ -4370,7 +4424,7 @@ static int ocfs2_downconvert_thread(void *arg)
|
||||
}
|
||||
|
||||
osb->dc_task = NULL;
|
||||
return status;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ocfs2_wake_downconvert_thread(struct ocfs2_super *osb)
|
||||
|
@@ -424,12 +424,11 @@ void ocfs2_shutdown_local_alloc(struct ocfs2_super *osb)
|
||||
bh = osb->local_alloc_bh;
|
||||
alloc = (struct ocfs2_dinode *) bh->b_data;
|
||||
|
||||
alloc_copy = kmalloc(bh->b_size, GFP_NOFS);
|
||||
alloc_copy = kmemdup(alloc, bh->b_size, GFP_NOFS);
|
||||
if (!alloc_copy) {
|
||||
status = -ENOMEM;
|
||||
goto out_commit;
|
||||
}
|
||||
memcpy(alloc_copy, alloc, bh->b_size);
|
||||
|
||||
status = ocfs2_journal_access_di(handle, INODE_CACHE(local_alloc_inode),
|
||||
bh, OCFS2_JOURNAL_ACCESS_WRITE);
|
||||
@@ -1272,13 +1271,12 @@ static int ocfs2_local_alloc_slide_window(struct ocfs2_super *osb,
|
||||
* local alloc shutdown won't try to double free main bitmap
|
||||
* bits. Make a copy so the sync function knows which bits to
|
||||
* free. */
|
||||
alloc_copy = kmalloc(osb->local_alloc_bh->b_size, GFP_NOFS);
|
||||
alloc_copy = kmemdup(alloc, osb->local_alloc_bh->b_size, GFP_NOFS);
|
||||
if (!alloc_copy) {
|
||||
status = -ENOMEM;
|
||||
mlog_errno(status);
|
||||
goto bail;
|
||||
}
|
||||
memcpy(alloc_copy, alloc, osb->local_alloc_bh->b_size);
|
||||
|
||||
status = ocfs2_journal_access_di(handle,
|
||||
INODE_CACHE(local_alloc_inode),
|
||||
|
@@ -150,6 +150,7 @@ struct ocfs2_lock_stats {
|
||||
|
||||
/* Storing max wait in usecs saves 24 bytes per inode */
|
||||
u32 ls_max; /* Max wait in USEC */
|
||||
u64 ls_last; /* Last unlock time in USEC */
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -191,6 +192,7 @@ struct ocfs2_lock_res {
|
||||
#ifdef CONFIG_OCFS2_FS_STATS
|
||||
struct ocfs2_lock_stats l_lock_prmode; /* PR mode stats */
|
||||
u32 l_lock_refresh; /* Disk refreshes */
|
||||
u64 l_lock_wait; /* First lock wait time */
|
||||
struct ocfs2_lock_stats l_lock_exmode; /* EX mode stats */
|
||||
#endif
|
||||
#ifdef CONFIG_DEBUG_LOCK_ALLOC
|
||||
@@ -222,6 +224,8 @@ struct ocfs2_orphan_scan {
|
||||
struct ocfs2_dlm_debug {
|
||||
struct kref d_refcnt;
|
||||
struct dentry *d_locking_state;
|
||||
struct dentry *d_locking_filter;
|
||||
u32 d_filter_secs;
|
||||
struct list_head d_lockres_tracking;
|
||||
};
|
||||
|
||||
|
@@ -1079,33 +1079,15 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
|
||||
|
||||
osb->osb_debug_root = debugfs_create_dir(osb->uuid_str,
|
||||
ocfs2_debugfs_root);
|
||||
if (!osb->osb_debug_root) {
|
||||
status = -EINVAL;
|
||||
mlog(ML_ERROR, "Unable to create per-mount debugfs root.\n");
|
||||
goto read_super_error;
|
||||
}
|
||||
|
||||
osb->osb_ctxt = debugfs_create_file("fs_state", S_IFREG|S_IRUSR,
|
||||
osb->osb_debug_root,
|
||||
osb,
|
||||
&ocfs2_osb_debug_fops);
|
||||
if (!osb->osb_ctxt) {
|
||||
status = -EINVAL;
|
||||
mlog_errno(status);
|
||||
goto read_super_error;
|
||||
}
|
||||
|
||||
if (ocfs2_meta_ecc(osb)) {
|
||||
status = ocfs2_blockcheck_stats_debugfs_install(
|
||||
&osb->osb_ecc_stats,
|
||||
osb->osb_debug_root);
|
||||
if (status) {
|
||||
mlog(ML_ERROR,
|
||||
"Unable to create blockcheck statistics "
|
||||
"files\n");
|
||||
goto read_super_error;
|
||||
}
|
||||
}
|
||||
if (ocfs2_meta_ecc(osb))
|
||||
ocfs2_blockcheck_stats_debugfs_install( &osb->osb_ecc_stats,
|
||||
osb->osb_debug_root);
|
||||
|
||||
status = ocfs2_mount_volume(sb);
|
||||
if (status < 0)
|
||||
@@ -1592,11 +1574,6 @@ static int __init ocfs2_init(void)
|
||||
goto out2;
|
||||
|
||||
ocfs2_debugfs_root = debugfs_create_dir("ocfs2", NULL);
|
||||
if (!ocfs2_debugfs_root) {
|
||||
status = -ENOMEM;
|
||||
mlog(ML_ERROR, "Unable to create ocfs2 debugfs root.\n");
|
||||
goto out3;
|
||||
}
|
||||
|
||||
ocfs2_set_locking_protocol();
|
||||
|
||||
|
@@ -532,8 +532,7 @@ static int proc_oom_score(struct seq_file *m, struct pid_namespace *ns,
|
||||
unsigned long totalpages = totalram_pages() + total_swap_pages;
|
||||
unsigned long points = 0;
|
||||
|
||||
points = oom_badness(task, NULL, NULL, totalpages) *
|
||||
1000 / totalpages;
|
||||
points = oom_badness(task, totalpages) * 1000 / totalpages;
|
||||
seq_printf(m, "%lu\n", points);
|
||||
|
||||
return 0;
|
||||
@@ -1962,9 +1961,12 @@ static int map_files_d_revalidate(struct dentry *dentry, unsigned int flags)
|
||||
goto out;
|
||||
|
||||
if (!dname_to_vma_addr(dentry, &vm_start, &vm_end)) {
|
||||
down_read(&mm->mmap_sem);
|
||||
exact_vma_exists = !!find_exact_vma(mm, vm_start, vm_end);
|
||||
up_read(&mm->mmap_sem);
|
||||
status = down_read_killable(&mm->mmap_sem);
|
||||
if (!status) {
|
||||
exact_vma_exists = !!find_exact_vma(mm, vm_start,
|
||||
vm_end);
|
||||
up_read(&mm->mmap_sem);
|
||||
}
|
||||
}
|
||||
|
||||
mmput(mm);
|
||||
@@ -2010,8 +2012,11 @@ static int map_files_get_link(struct dentry *dentry, struct path *path)
|
||||
if (rc)
|
||||
goto out_mmput;
|
||||
|
||||
rc = down_read_killable(&mm->mmap_sem);
|
||||
if (rc)
|
||||
goto out_mmput;
|
||||
|
||||
rc = -ENOENT;
|
||||
down_read(&mm->mmap_sem);
|
||||
vma = find_exact_vma(mm, vm_start, vm_end);
|
||||
if (vma && vma->vm_file) {
|
||||
*path = vma->vm_file->f_path;
|
||||
@@ -2107,7 +2112,11 @@ static struct dentry *proc_map_files_lookup(struct inode *dir,
|
||||
if (!mm)
|
||||
goto out_put_task;
|
||||
|
||||
down_read(&mm->mmap_sem);
|
||||
result = ERR_PTR(-EINTR);
|
||||
if (down_read_killable(&mm->mmap_sem))
|
||||
goto out_put_mm;
|
||||
|
||||
result = ERR_PTR(-ENOENT);
|
||||
vma = find_exact_vma(mm, vm_start, vm_end);
|
||||
if (!vma)
|
||||
goto out_no_vma;
|
||||
@@ -2118,6 +2127,7 @@ static struct dentry *proc_map_files_lookup(struct inode *dir,
|
||||
|
||||
out_no_vma:
|
||||
up_read(&mm->mmap_sem);
|
||||
out_put_mm:
|
||||
mmput(mm);
|
||||
out_put_task:
|
||||
put_task_struct(task);
|
||||
@@ -2160,7 +2170,12 @@ proc_map_files_readdir(struct file *file, struct dir_context *ctx)
|
||||
mm = get_task_mm(task);
|
||||
if (!mm)
|
||||
goto out_put_task;
|
||||
down_read(&mm->mmap_sem);
|
||||
|
||||
ret = down_read_killable(&mm->mmap_sem);
|
||||
if (ret) {
|
||||
mmput(mm);
|
||||
goto out_put_task;
|
||||
}
|
||||
|
||||
nr_files = 0;
|
||||
|
||||
|
@@ -120,7 +120,7 @@ static int meminfo_proc_show(struct seq_file *m, void *v)
|
||||
show_val_kb(m, "Committed_AS: ", committed);
|
||||
seq_printf(m, "VmallocTotal: %8lu kB\n",
|
||||
(unsigned long)VMALLOC_TOTAL >> 10);
|
||||
show_val_kb(m, "VmallocUsed: ", 0ul);
|
||||
show_val_kb(m, "VmallocUsed: ", vmalloc_nr_pages());
|
||||
show_val_kb(m, "VmallocChunk: ", 0ul);
|
||||
show_val_kb(m, "Percpu: ", pcpu_nr_pages());
|
||||
|
||||
|
@@ -166,7 +166,11 @@ static void *m_start(struct seq_file *m, loff_t *ppos)
|
||||
if (!mm || !mmget_not_zero(mm))
|
||||
return NULL;
|
||||
|
||||
down_read(&mm->mmap_sem);
|
||||
if (down_read_killable(&mm->mmap_sem)) {
|
||||
mmput(mm);
|
||||
return ERR_PTR(-EINTR);
|
||||
}
|
||||
|
||||
hold_task_mempolicy(priv);
|
||||
priv->tail_vma = get_gate_vma(mm);
|
||||
|
||||
@@ -417,17 +421,53 @@ struct mem_size_stats {
|
||||
unsigned long shared_hugetlb;
|
||||
unsigned long private_hugetlb;
|
||||
u64 pss;
|
||||
u64 pss_anon;
|
||||
u64 pss_file;
|
||||
u64 pss_shmem;
|
||||
u64 pss_locked;
|
||||
u64 swap_pss;
|
||||
bool check_shmem_swap;
|
||||
};
|
||||
|
||||
static void smaps_page_accumulate(struct mem_size_stats *mss,
|
||||
struct page *page, unsigned long size, unsigned long pss,
|
||||
bool dirty, bool locked, bool private)
|
||||
{
|
||||
mss->pss += pss;
|
||||
|
||||
if (PageAnon(page))
|
||||
mss->pss_anon += pss;
|
||||
else if (PageSwapBacked(page))
|
||||
mss->pss_shmem += pss;
|
||||
else
|
||||
mss->pss_file += pss;
|
||||
|
||||
if (locked)
|
||||
mss->pss_locked += pss;
|
||||
|
||||
if (dirty || PageDirty(page)) {
|
||||
if (private)
|
||||
mss->private_dirty += size;
|
||||
else
|
||||
mss->shared_dirty += size;
|
||||
} else {
|
||||
if (private)
|
||||
mss->private_clean += size;
|
||||
else
|
||||
mss->shared_clean += size;
|
||||
}
|
||||
}
|
||||
|
||||
static void smaps_account(struct mem_size_stats *mss, struct page *page,
|
||||
bool compound, bool young, bool dirty, bool locked)
|
||||
{
|
||||
int i, nr = compound ? 1 << compound_order(page) : 1;
|
||||
unsigned long size = nr * PAGE_SIZE;
|
||||
|
||||
/*
|
||||
* First accumulate quantities that depend only on |size| and the type
|
||||
* of the compound page.
|
||||
*/
|
||||
if (PageAnon(page)) {
|
||||
mss->anonymous += size;
|
||||
if (!PageSwapBacked(page) && !dirty && !PageDirty(page))
|
||||
@@ -440,42 +480,25 @@ static void smaps_account(struct mem_size_stats *mss, struct page *page,
|
||||
mss->referenced += size;
|
||||
|
||||
/*
|
||||
* Then accumulate quantities that may depend on sharing, or that may
|
||||
* differ page-by-page.
|
||||
*
|
||||
* page_count(page) == 1 guarantees the page is mapped exactly once.
|
||||
* If any subpage of the compound page mapped with PTE it would elevate
|
||||
* page_count().
|
||||
*/
|
||||
if (page_count(page) == 1) {
|
||||
if (dirty || PageDirty(page))
|
||||
mss->private_dirty += size;
|
||||
else
|
||||
mss->private_clean += size;
|
||||
mss->pss += (u64)size << PSS_SHIFT;
|
||||
if (locked)
|
||||
mss->pss_locked += (u64)size << PSS_SHIFT;
|
||||
smaps_page_accumulate(mss, page, size, size << PSS_SHIFT, dirty,
|
||||
locked, true);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < nr; i++, page++) {
|
||||
int mapcount = page_mapcount(page);
|
||||
unsigned long pss = (PAGE_SIZE << PSS_SHIFT);
|
||||
|
||||
if (mapcount >= 2) {
|
||||
if (dirty || PageDirty(page))
|
||||
mss->shared_dirty += PAGE_SIZE;
|
||||
else
|
||||
mss->shared_clean += PAGE_SIZE;
|
||||
mss->pss += pss / mapcount;
|
||||
if (locked)
|
||||
mss->pss_locked += pss / mapcount;
|
||||
} else {
|
||||
if (dirty || PageDirty(page))
|
||||
mss->private_dirty += PAGE_SIZE;
|
||||
else
|
||||
mss->private_clean += PAGE_SIZE;
|
||||
mss->pss += pss;
|
||||
if (locked)
|
||||
mss->pss_locked += pss;
|
||||
}
|
||||
unsigned long pss = PAGE_SIZE << PSS_SHIFT;
|
||||
if (mapcount >= 2)
|
||||
pss /= mapcount;
|
||||
smaps_page_accumulate(mss, page, PAGE_SIZE, pss, dirty, locked,
|
||||
mapcount < 2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -754,10 +777,23 @@ static void smap_gather_stats(struct vm_area_struct *vma,
|
||||
seq_put_decimal_ull_width(m, str, (val) >> 10, 8)
|
||||
|
||||
/* Show the contents common for smaps and smaps_rollup */
|
||||
static void __show_smap(struct seq_file *m, const struct mem_size_stats *mss)
|
||||
static void __show_smap(struct seq_file *m, const struct mem_size_stats *mss,
|
||||
bool rollup_mode)
|
||||
{
|
||||
SEQ_PUT_DEC("Rss: ", mss->resident);
|
||||
SEQ_PUT_DEC(" kB\nPss: ", mss->pss >> PSS_SHIFT);
|
||||
if (rollup_mode) {
|
||||
/*
|
||||
* These are meaningful only for smaps_rollup, otherwise two of
|
||||
* them are zero, and the other one is the same as Pss.
|
||||
*/
|
||||
SEQ_PUT_DEC(" kB\nPss_Anon: ",
|
||||
mss->pss_anon >> PSS_SHIFT);
|
||||
SEQ_PUT_DEC(" kB\nPss_File: ",
|
||||
mss->pss_file >> PSS_SHIFT);
|
||||
SEQ_PUT_DEC(" kB\nPss_Shmem: ",
|
||||
mss->pss_shmem >> PSS_SHIFT);
|
||||
}
|
||||
SEQ_PUT_DEC(" kB\nShared_Clean: ", mss->shared_clean);
|
||||
SEQ_PUT_DEC(" kB\nShared_Dirty: ", mss->shared_dirty);
|
||||
SEQ_PUT_DEC(" kB\nPrivate_Clean: ", mss->private_clean);
|
||||
@@ -794,7 +830,7 @@ static int show_smap(struct seq_file *m, void *v)
|
||||
SEQ_PUT_DEC(" kB\nMMUPageSize: ", vma_mmu_pagesize(vma));
|
||||
seq_puts(m, " kB\n");
|
||||
|
||||
__show_smap(m, &mss);
|
||||
__show_smap(m, &mss, false);
|
||||
|
||||
seq_printf(m, "THPeligible: %d\n", transparent_hugepage_enabled(vma));
|
||||
|
||||
@@ -828,7 +864,10 @@ static int show_smaps_rollup(struct seq_file *m, void *v)
|
||||
|
||||
memset(&mss, 0, sizeof(mss));
|
||||
|
||||
down_read(&mm->mmap_sem);
|
||||
ret = down_read_killable(&mm->mmap_sem);
|
||||
if (ret)
|
||||
goto out_put_mm;
|
||||
|
||||
hold_task_mempolicy(priv);
|
||||
|
||||
for (vma = priv->mm->mmap; vma; vma = vma->vm_next) {
|
||||
@@ -841,12 +880,13 @@ static int show_smaps_rollup(struct seq_file *m, void *v)
|
||||
seq_pad(m, ' ');
|
||||
seq_puts(m, "[rollup]\n");
|
||||
|
||||
__show_smap(m, &mss);
|
||||
__show_smap(m, &mss, true);
|
||||
|
||||
release_task_mempolicy(priv);
|
||||
up_read(&mm->mmap_sem);
|
||||
mmput(mm);
|
||||
|
||||
out_put_mm:
|
||||
mmput(mm);
|
||||
out_put_task:
|
||||
put_task_struct(priv->task);
|
||||
priv->task = NULL;
|
||||
@@ -1132,7 +1172,10 @@ static ssize_t clear_refs_write(struct file *file, const char __user *buf,
|
||||
goto out_mm;
|
||||
}
|
||||
|
||||
down_read(&mm->mmap_sem);
|
||||
if (down_read_killable(&mm->mmap_sem)) {
|
||||
count = -EINTR;
|
||||
goto out_mm;
|
||||
}
|
||||
tlb_gather_mmu(&tlb, mm, 0, -1);
|
||||
if (type == CLEAR_REFS_SOFT_DIRTY) {
|
||||
for (vma = mm->mmap; vma; vma = vma->vm_next) {
|
||||
@@ -1539,7 +1582,9 @@ static ssize_t pagemap_read(struct file *file, char __user *buf,
|
||||
/* overflow ? */
|
||||
if (end < start_vaddr || end > end_vaddr)
|
||||
end = end_vaddr;
|
||||
down_read(&mm->mmap_sem);
|
||||
ret = down_read_killable(&mm->mmap_sem);
|
||||
if (ret)
|
||||
goto out_free;
|
||||
ret = walk_page_range(start_vaddr, end, &pagemap_walk);
|
||||
up_read(&mm->mmap_sem);
|
||||
start_vaddr = end;
|
||||
|
@@ -211,7 +211,11 @@ static void *m_start(struct seq_file *m, loff_t *pos)
|
||||
if (!mm || !mmget_not_zero(mm))
|
||||
return NULL;
|
||||
|
||||
down_read(&mm->mmap_sem);
|
||||
if (down_read_killable(&mm->mmap_sem)) {
|
||||
mmput(mm);
|
||||
return ERR_PTR(-EINTR);
|
||||
}
|
||||
|
||||
/* start from the Nth VMA */
|
||||
for (p = rb_first(&mm->mm_rb); p; p = rb_next(p))
|
||||
if (n-- == 0)
|
||||
|
新增問題並參考
封鎖使用者