mirror of
https://github.com/torvalds/linux.git
synced 2024-11-22 04:02:20 +00:00
Merge branch 'akpm' (patches from Andrew)
Merge misc fixes from Andrew Morton: "Rather a lot of fixes, almost all affecting mm/" * emailed patches from Andrew Morton <akpm@linux-foundation.org>: (26 commits) scripts/gdb: fix debugging modules on s390 kernel/events/uprobes.c: only do FOLL_SPLIT_PMD for uprobe register mm/thp: allow dropping THP from page cache mm/vmscan.c: support removing arbitrary sized pages from mapping mm/thp: fix node page state in split_huge_page_to_list() proc/meminfo: fix output alignment mm/init-mm.c: include <linux/mman.h> for vm_committed_as_batch mm/filemap.c: include <linux/ramfs.h> for generic_file_vm_ops definition mm: include <linux/huge_mm.h> for is_vma_temporary_stack zram: fix race between backing_dev_show and backing_dev_store mm/memcontrol: update lruvec counters in mem_cgroup_move_account ocfs2: fix panic due to ocfs2_wq is null hugetlbfs: don't access uninitialized memmaps in pfn_range_valid_gigantic() mm: memblock: do not enforce current limit for memblock_phys* family mm: memcg: get number of pages on the LRU list in memcgroup base on lru_zone_size mm/gup: fix a misnamed "write" argument, and a related bug mm/gup_benchmark: add a missing "w" to getopt string ocfs2: fix error handling in ocfs2_setattr() mm: memcg/slab: fix panic in __free_slab() caused by premature memcg pointer release mm/memunmap: don't access uninitialized memmap in memunmap_pages() ...
This commit is contained in:
commit
998d75510e
@ -540,6 +540,9 @@ static ssize_t soft_offline_page_store(struct device *dev,
|
|||||||
pfn >>= PAGE_SHIFT;
|
pfn >>= PAGE_SHIFT;
|
||||||
if (!pfn_valid(pfn))
|
if (!pfn_valid(pfn))
|
||||||
return -ENXIO;
|
return -ENXIO;
|
||||||
|
/* Only online pages can be soft-offlined (esp., not ZONE_DEVICE). */
|
||||||
|
if (!pfn_to_online_page(pfn))
|
||||||
|
return -EIO;
|
||||||
ret = soft_offline_page(pfn_to_page(pfn), 0);
|
ret = soft_offline_page(pfn_to_page(pfn), 0);
|
||||||
return ret == 0 ? count : ret;
|
return ret == 0 ? count : ret;
|
||||||
}
|
}
|
||||||
|
@ -413,13 +413,14 @@ static void reset_bdev(struct zram *zram)
|
|||||||
static ssize_t backing_dev_show(struct device *dev,
|
static ssize_t backing_dev_show(struct device *dev,
|
||||||
struct device_attribute *attr, char *buf)
|
struct device_attribute *attr, char *buf)
|
||||||
{
|
{
|
||||||
|
struct file *file;
|
||||||
struct zram *zram = dev_to_zram(dev);
|
struct zram *zram = dev_to_zram(dev);
|
||||||
struct file *file = zram->backing_dev;
|
|
||||||
char *p;
|
char *p;
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
|
|
||||||
down_read(&zram->init_lock);
|
down_read(&zram->init_lock);
|
||||||
if (!zram->backing_dev) {
|
file = zram->backing_dev;
|
||||||
|
if (!file) {
|
||||||
memcpy(buf, "none\n", 5);
|
memcpy(buf, "none\n", 5);
|
||||||
up_read(&zram->init_lock);
|
up_read(&zram->init_lock);
|
||||||
return 5;
|
return 5;
|
||||||
|
@ -1230,6 +1230,7 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr)
|
|||||||
transfer_to[USRQUOTA] = dqget(sb, make_kqid_uid(attr->ia_uid));
|
transfer_to[USRQUOTA] = dqget(sb, make_kqid_uid(attr->ia_uid));
|
||||||
if (IS_ERR(transfer_to[USRQUOTA])) {
|
if (IS_ERR(transfer_to[USRQUOTA])) {
|
||||||
status = PTR_ERR(transfer_to[USRQUOTA]);
|
status = PTR_ERR(transfer_to[USRQUOTA]);
|
||||||
|
transfer_to[USRQUOTA] = NULL;
|
||||||
goto bail_unlock;
|
goto bail_unlock;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1239,6 +1240,7 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr)
|
|||||||
transfer_to[GRPQUOTA] = dqget(sb, make_kqid_gid(attr->ia_gid));
|
transfer_to[GRPQUOTA] = dqget(sb, make_kqid_gid(attr->ia_gid));
|
||||||
if (IS_ERR(transfer_to[GRPQUOTA])) {
|
if (IS_ERR(transfer_to[GRPQUOTA])) {
|
||||||
status = PTR_ERR(transfer_to[GRPQUOTA]);
|
status = PTR_ERR(transfer_to[GRPQUOTA]);
|
||||||
|
transfer_to[GRPQUOTA] = NULL;
|
||||||
goto bail_unlock;
|
goto bail_unlock;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -217,7 +217,8 @@ void ocfs2_recovery_exit(struct ocfs2_super *osb)
|
|||||||
/* At this point, we know that no more recovery threads can be
|
/* At this point, we know that no more recovery threads can be
|
||||||
* launched, so wait for any recovery completion work to
|
* launched, so wait for any recovery completion work to
|
||||||
* complete. */
|
* complete. */
|
||||||
flush_workqueue(osb->ocfs2_wq);
|
if (osb->ocfs2_wq)
|
||||||
|
flush_workqueue(osb->ocfs2_wq);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Now that recovery is shut down, and the osb is about to be
|
* Now that recovery is shut down, and the osb is about to be
|
||||||
|
@ -377,7 +377,8 @@ void ocfs2_shutdown_local_alloc(struct ocfs2_super *osb)
|
|||||||
struct ocfs2_dinode *alloc = NULL;
|
struct ocfs2_dinode *alloc = NULL;
|
||||||
|
|
||||||
cancel_delayed_work(&osb->la_enable_wq);
|
cancel_delayed_work(&osb->la_enable_wq);
|
||||||
flush_workqueue(osb->ocfs2_wq);
|
if (osb->ocfs2_wq)
|
||||||
|
flush_workqueue(osb->ocfs2_wq);
|
||||||
|
|
||||||
if (osb->local_alloc_state == OCFS2_LA_UNUSED)
|
if (osb->local_alloc_state == OCFS2_LA_UNUSED)
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -132,9 +132,9 @@ static int meminfo_proc_show(struct seq_file *m, void *v)
|
|||||||
global_node_page_state(NR_SHMEM_THPS) * HPAGE_PMD_NR);
|
global_node_page_state(NR_SHMEM_THPS) * HPAGE_PMD_NR);
|
||||||
show_val_kb(m, "ShmemPmdMapped: ",
|
show_val_kb(m, "ShmemPmdMapped: ",
|
||||||
global_node_page_state(NR_SHMEM_PMDMAPPED) * HPAGE_PMD_NR);
|
global_node_page_state(NR_SHMEM_PMDMAPPED) * HPAGE_PMD_NR);
|
||||||
show_val_kb(m, "FileHugePages: ",
|
show_val_kb(m, "FileHugePages: ",
|
||||||
global_node_page_state(NR_FILE_THPS) * HPAGE_PMD_NR);
|
global_node_page_state(NR_FILE_THPS) * HPAGE_PMD_NR);
|
||||||
show_val_kb(m, "FilePmdMapped: ",
|
show_val_kb(m, "FilePmdMapped: ",
|
||||||
global_node_page_state(NR_FILE_PMDMAPPED) * HPAGE_PMD_NR);
|
global_node_page_state(NR_FILE_PMDMAPPED) * HPAGE_PMD_NR);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -42,10 +42,12 @@ static ssize_t kpagecount_read(struct file *file, char __user *buf,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
while (count > 0) {
|
while (count > 0) {
|
||||||
if (pfn_valid(pfn))
|
/*
|
||||||
ppage = pfn_to_page(pfn);
|
* TODO: ZONE_DEVICE support requires to identify
|
||||||
else
|
* memmaps that were actually initialized.
|
||||||
ppage = NULL;
|
*/
|
||||||
|
ppage = pfn_to_online_page(pfn);
|
||||||
|
|
||||||
if (!ppage || PageSlab(ppage) || page_has_type(ppage))
|
if (!ppage || PageSlab(ppage) || page_has_type(ppage))
|
||||||
pcount = 0;
|
pcount = 0;
|
||||||
else
|
else
|
||||||
@ -216,10 +218,11 @@ static ssize_t kpageflags_read(struct file *file, char __user *buf,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
while (count > 0) {
|
while (count > 0) {
|
||||||
if (pfn_valid(pfn))
|
/*
|
||||||
ppage = pfn_to_page(pfn);
|
* TODO: ZONE_DEVICE support requires to identify
|
||||||
else
|
* memmaps that were actually initialized.
|
||||||
ppage = NULL;
|
*/
|
||||||
|
ppage = pfn_to_online_page(pfn);
|
||||||
|
|
||||||
if (put_user(stable_page_flags(ppage), out)) {
|
if (put_user(stable_page_flags(ppage), out)) {
|
||||||
ret = -EFAULT;
|
ret = -EFAULT;
|
||||||
@ -261,10 +264,11 @@ static ssize_t kpagecgroup_read(struct file *file, char __user *buf,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
while (count > 0) {
|
while (count > 0) {
|
||||||
if (pfn_valid(pfn))
|
/*
|
||||||
ppage = pfn_to_page(pfn);
|
* TODO: ZONE_DEVICE support requires to identify
|
||||||
else
|
* memmaps that were actually initialized.
|
||||||
ppage = NULL;
|
*/
|
||||||
|
ppage = pfn_to_online_page(pfn);
|
||||||
|
|
||||||
if (ppage)
|
if (ppage)
|
||||||
ino = page_cgroup_ino(ppage);
|
ino = page_cgroup_ino(ppage);
|
||||||
|
@ -474,14 +474,17 @@ int uprobe_write_opcode(struct arch_uprobe *auprobe, struct mm_struct *mm,
|
|||||||
struct vm_area_struct *vma;
|
struct vm_area_struct *vma;
|
||||||
int ret, is_register, ref_ctr_updated = 0;
|
int ret, is_register, ref_ctr_updated = 0;
|
||||||
bool orig_page_huge = false;
|
bool orig_page_huge = false;
|
||||||
|
unsigned int gup_flags = FOLL_FORCE;
|
||||||
|
|
||||||
is_register = is_swbp_insn(&opcode);
|
is_register = is_swbp_insn(&opcode);
|
||||||
uprobe = container_of(auprobe, struct uprobe, arch);
|
uprobe = container_of(auprobe, struct uprobe, arch);
|
||||||
|
|
||||||
retry:
|
retry:
|
||||||
|
if (is_register)
|
||||||
|
gup_flags |= FOLL_SPLIT_PMD;
|
||||||
/* Read the page with vaddr into memory */
|
/* Read the page with vaddr into memory */
|
||||||
ret = get_user_pages_remote(NULL, mm, vaddr, 1,
|
ret = get_user_pages_remote(NULL, mm, vaddr, 1, gup_flags,
|
||||||
FOLL_FORCE | FOLL_SPLIT_PMD, &old_page, &vma, NULL);
|
&old_page, &vma, NULL);
|
||||||
if (ret <= 0)
|
if (ret <= 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
@ -489,6 +492,12 @@ retry:
|
|||||||
if (ret <= 0)
|
if (ret <= 0)
|
||||||
goto put_old;
|
goto put_old;
|
||||||
|
|
||||||
|
if (WARN(!is_register && PageCompound(old_page),
|
||||||
|
"uprobe unregister should never work on compound page\n")) {
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto put_old;
|
||||||
|
}
|
||||||
|
|
||||||
/* We are going to replace instruction, update ref_ctr. */
|
/* We are going to replace instruction, update ref_ctr. */
|
||||||
if (!ref_ctr_updated && uprobe->ref_ctr_offset) {
|
if (!ref_ctr_updated && uprobe->ref_ctr_offset) {
|
||||||
ret = update_ref_ctr(uprobe, mm, is_register ? 1 : -1);
|
ret = update_ref_ctr(uprobe, mm, is_register ? 1 : -1);
|
||||||
|
@ -40,6 +40,7 @@
|
|||||||
#include <linux/rmap.h>
|
#include <linux/rmap.h>
|
||||||
#include <linux/delayacct.h>
|
#include <linux/delayacct.h>
|
||||||
#include <linux/psi.h>
|
#include <linux/psi.h>
|
||||||
|
#include <linux/ramfs.h>
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
#define CREATE_TRACE_POINTS
|
#define CREATE_TRACE_POINTS
|
||||||
|
14
mm/gup.c
14
mm/gup.c
@ -1973,7 +1973,8 @@ static unsigned long hugepte_addr_end(unsigned long addr, unsigned long end,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long addr,
|
static int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long addr,
|
||||||
unsigned long end, int write, struct page **pages, int *nr)
|
unsigned long end, unsigned int flags,
|
||||||
|
struct page **pages, int *nr)
|
||||||
{
|
{
|
||||||
unsigned long pte_end;
|
unsigned long pte_end;
|
||||||
struct page *head, *page;
|
struct page *head, *page;
|
||||||
@ -1986,7 +1987,7 @@ static int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long addr,
|
|||||||
|
|
||||||
pte = READ_ONCE(*ptep);
|
pte = READ_ONCE(*ptep);
|
||||||
|
|
||||||
if (!pte_access_permitted(pte, write))
|
if (!pte_access_permitted(pte, flags & FOLL_WRITE))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* hugepages are never "special" */
|
/* hugepages are never "special" */
|
||||||
@ -2023,7 +2024,7 @@ static int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long addr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int gup_huge_pd(hugepd_t hugepd, unsigned long addr,
|
static int gup_huge_pd(hugepd_t hugepd, unsigned long addr,
|
||||||
unsigned int pdshift, unsigned long end, int write,
|
unsigned int pdshift, unsigned long end, unsigned int flags,
|
||||||
struct page **pages, int *nr)
|
struct page **pages, int *nr)
|
||||||
{
|
{
|
||||||
pte_t *ptep;
|
pte_t *ptep;
|
||||||
@ -2033,7 +2034,7 @@ static int gup_huge_pd(hugepd_t hugepd, unsigned long addr,
|
|||||||
ptep = hugepte_offset(hugepd, addr, pdshift);
|
ptep = hugepte_offset(hugepd, addr, pdshift);
|
||||||
do {
|
do {
|
||||||
next = hugepte_addr_end(addr, end, sz);
|
next = hugepte_addr_end(addr, end, sz);
|
||||||
if (!gup_hugepte(ptep, sz, addr, end, write, pages, nr))
|
if (!gup_hugepte(ptep, sz, addr, end, flags, pages, nr))
|
||||||
return 0;
|
return 0;
|
||||||
} while (ptep++, addr = next, addr != end);
|
} while (ptep++, addr = next, addr != end);
|
||||||
|
|
||||||
@ -2041,7 +2042,7 @@ static int gup_huge_pd(hugepd_t hugepd, unsigned long addr,
|
|||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
static inline int gup_huge_pd(hugepd_t hugepd, unsigned long addr,
|
static inline int gup_huge_pd(hugepd_t hugepd, unsigned long addr,
|
||||||
unsigned pdshift, unsigned long end, int write,
|
unsigned int pdshift, unsigned long end, unsigned int flags,
|
||||||
struct page **pages, int *nr)
|
struct page **pages, int *nr)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
@ -2049,7 +2050,8 @@ static inline int gup_huge_pd(hugepd_t hugepd, unsigned long addr,
|
|||||||
#endif /* CONFIG_ARCH_HAS_HUGEPD */
|
#endif /* CONFIG_ARCH_HAS_HUGEPD */
|
||||||
|
|
||||||
static int gup_huge_pmd(pmd_t orig, pmd_t *pmdp, unsigned long addr,
|
static int gup_huge_pmd(pmd_t orig, pmd_t *pmdp, unsigned long addr,
|
||||||
unsigned long end, unsigned int flags, struct page **pages, int *nr)
|
unsigned long end, unsigned int flags,
|
||||||
|
struct page **pages, int *nr)
|
||||||
{
|
{
|
||||||
struct page *head, *page;
|
struct page *head, *page;
|
||||||
int refs;
|
int refs;
|
||||||
|
@ -2789,8 +2789,13 @@ int split_huge_page_to_list(struct page *page, struct list_head *list)
|
|||||||
ds_queue->split_queue_len--;
|
ds_queue->split_queue_len--;
|
||||||
list_del(page_deferred_list(head));
|
list_del(page_deferred_list(head));
|
||||||
}
|
}
|
||||||
if (mapping)
|
if (mapping) {
|
||||||
__dec_node_page_state(page, NR_SHMEM_THPS);
|
if (PageSwapBacked(page))
|
||||||
|
__dec_node_page_state(page, NR_SHMEM_THPS);
|
||||||
|
else
|
||||||
|
__dec_node_page_state(page, NR_FILE_THPS);
|
||||||
|
}
|
||||||
|
|
||||||
spin_unlock(&ds_queue->split_queue_lock);
|
spin_unlock(&ds_queue->split_queue_lock);
|
||||||
__split_huge_page(page, list, end, flags);
|
__split_huge_page(page, list, end, flags);
|
||||||
if (PageSwapCache(head)) {
|
if (PageSwapCache(head)) {
|
||||||
|
@ -1084,11 +1084,10 @@ static bool pfn_range_valid_gigantic(struct zone *z,
|
|||||||
struct page *page;
|
struct page *page;
|
||||||
|
|
||||||
for (i = start_pfn; i < end_pfn; i++) {
|
for (i = start_pfn; i < end_pfn; i++) {
|
||||||
if (!pfn_valid(i))
|
page = pfn_to_online_page(i);
|
||||||
|
if (!page)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
page = pfn_to_page(i);
|
|
||||||
|
|
||||||
if (page_zone(page) != z)
|
if (page_zone(page) != z)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include <linux/spinlock.h>
|
#include <linux/spinlock.h>
|
||||||
#include <linux/list.h>
|
#include <linux/list.h>
|
||||||
#include <linux/cpumask.h>
|
#include <linux/cpumask.h>
|
||||||
|
#include <linux/mman.h>
|
||||||
|
|
||||||
#include <linux/atomic.h>
|
#include <linux/atomic.h>
|
||||||
#include <linux/user_namespace.h>
|
#include <linux/user_namespace.h>
|
||||||
|
@ -1356,9 +1356,6 @@ static phys_addr_t __init memblock_alloc_range_nid(phys_addr_t size,
|
|||||||
align = SMP_CACHE_BYTES;
|
align = SMP_CACHE_BYTES;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (end > memblock.current_limit)
|
|
||||||
end = memblock.current_limit;
|
|
||||||
|
|
||||||
again:
|
again:
|
||||||
found = memblock_find_in_range_node(size, align, start, end, nid,
|
found = memblock_find_in_range_node(size, align, start, end, nid,
|
||||||
flags);
|
flags);
|
||||||
@ -1469,6 +1466,9 @@ static void * __init memblock_alloc_internal(
|
|||||||
if (WARN_ON_ONCE(slab_is_available()))
|
if (WARN_ON_ONCE(slab_is_available()))
|
||||||
return kzalloc_node(size, GFP_NOWAIT, nid);
|
return kzalloc_node(size, GFP_NOWAIT, nid);
|
||||||
|
|
||||||
|
if (max_addr > memblock.current_limit)
|
||||||
|
max_addr = memblock.current_limit;
|
||||||
|
|
||||||
alloc = memblock_alloc_range_nid(size, align, min_addr, max_addr, nid);
|
alloc = memblock_alloc_range_nid(size, align, min_addr, max_addr, nid);
|
||||||
|
|
||||||
/* retry allocation without lower limit */
|
/* retry allocation without lower limit */
|
||||||
|
@ -5420,6 +5420,8 @@ static int mem_cgroup_move_account(struct page *page,
|
|||||||
struct mem_cgroup *from,
|
struct mem_cgroup *from,
|
||||||
struct mem_cgroup *to)
|
struct mem_cgroup *to)
|
||||||
{
|
{
|
||||||
|
struct lruvec *from_vec, *to_vec;
|
||||||
|
struct pglist_data *pgdat;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
unsigned int nr_pages = compound ? hpage_nr_pages(page) : 1;
|
unsigned int nr_pages = compound ? hpage_nr_pages(page) : 1;
|
||||||
int ret;
|
int ret;
|
||||||
@ -5443,11 +5445,15 @@ static int mem_cgroup_move_account(struct page *page,
|
|||||||
|
|
||||||
anon = PageAnon(page);
|
anon = PageAnon(page);
|
||||||
|
|
||||||
|
pgdat = page_pgdat(page);
|
||||||
|
from_vec = mem_cgroup_lruvec(pgdat, from);
|
||||||
|
to_vec = mem_cgroup_lruvec(pgdat, to);
|
||||||
|
|
||||||
spin_lock_irqsave(&from->move_lock, flags);
|
spin_lock_irqsave(&from->move_lock, flags);
|
||||||
|
|
||||||
if (!anon && page_mapped(page)) {
|
if (!anon && page_mapped(page)) {
|
||||||
__mod_memcg_state(from, NR_FILE_MAPPED, -nr_pages);
|
__mod_lruvec_state(from_vec, NR_FILE_MAPPED, -nr_pages);
|
||||||
__mod_memcg_state(to, NR_FILE_MAPPED, nr_pages);
|
__mod_lruvec_state(to_vec, NR_FILE_MAPPED, nr_pages);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -5459,14 +5465,14 @@ static int mem_cgroup_move_account(struct page *page,
|
|||||||
struct address_space *mapping = page_mapping(page);
|
struct address_space *mapping = page_mapping(page);
|
||||||
|
|
||||||
if (mapping_cap_account_dirty(mapping)) {
|
if (mapping_cap_account_dirty(mapping)) {
|
||||||
__mod_memcg_state(from, NR_FILE_DIRTY, -nr_pages);
|
__mod_lruvec_state(from_vec, NR_FILE_DIRTY, -nr_pages);
|
||||||
__mod_memcg_state(to, NR_FILE_DIRTY, nr_pages);
|
__mod_lruvec_state(to_vec, NR_FILE_DIRTY, nr_pages);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PageWriteback(page)) {
|
if (PageWriteback(page)) {
|
||||||
__mod_memcg_state(from, NR_WRITEBACK, -nr_pages);
|
__mod_lruvec_state(from_vec, NR_WRITEBACK, -nr_pages);
|
||||||
__mod_memcg_state(to, NR_WRITEBACK, nr_pages);
|
__mod_lruvec_state(to_vec, NR_WRITEBACK, nr_pages);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
|
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
|
||||||
|
@ -1257,17 +1257,19 @@ int memory_failure(unsigned long pfn, int flags)
|
|||||||
if (!sysctl_memory_failure_recovery)
|
if (!sysctl_memory_failure_recovery)
|
||||||
panic("Memory failure on page %lx", pfn);
|
panic("Memory failure on page %lx", pfn);
|
||||||
|
|
||||||
if (!pfn_valid(pfn)) {
|
p = pfn_to_online_page(pfn);
|
||||||
|
if (!p) {
|
||||||
|
if (pfn_valid(pfn)) {
|
||||||
|
pgmap = get_dev_pagemap(pfn, NULL);
|
||||||
|
if (pgmap)
|
||||||
|
return memory_failure_dev_pagemap(pfn, flags,
|
||||||
|
pgmap);
|
||||||
|
}
|
||||||
pr_err("Memory failure: %#lx: memory outside kernel control\n",
|
pr_err("Memory failure: %#lx: memory outside kernel control\n",
|
||||||
pfn);
|
pfn);
|
||||||
return -ENXIO;
|
return -ENXIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
pgmap = get_dev_pagemap(pfn, NULL);
|
|
||||||
if (pgmap)
|
|
||||||
return memory_failure_dev_pagemap(pfn, flags, pgmap);
|
|
||||||
|
|
||||||
p = pfn_to_page(pfn);
|
|
||||||
if (PageHuge(p))
|
if (PageHuge(p))
|
||||||
return memory_failure_hugetlb(pfn, flags);
|
return memory_failure_hugetlb(pfn, flags);
|
||||||
if (TestSetPageHWPoison(p)) {
|
if (TestSetPageHWPoison(p)) {
|
||||||
|
@ -436,67 +436,25 @@ static void shrink_zone_span(struct zone *zone, unsigned long start_pfn,
|
|||||||
zone_span_writeunlock(zone);
|
zone_span_writeunlock(zone);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void shrink_pgdat_span(struct pglist_data *pgdat,
|
static void update_pgdat_span(struct pglist_data *pgdat)
|
||||||
unsigned long start_pfn, unsigned long end_pfn)
|
|
||||||
{
|
{
|
||||||
unsigned long pgdat_start_pfn = pgdat->node_start_pfn;
|
unsigned long node_start_pfn = 0, node_end_pfn = 0;
|
||||||
unsigned long p = pgdat_end_pfn(pgdat); /* pgdat_end_pfn namespace clash */
|
struct zone *zone;
|
||||||
unsigned long pgdat_end_pfn = p;
|
|
||||||
unsigned long pfn;
|
|
||||||
int nid = pgdat->node_id;
|
|
||||||
|
|
||||||
if (pgdat_start_pfn == start_pfn) {
|
for (zone = pgdat->node_zones;
|
||||||
/*
|
zone < pgdat->node_zones + MAX_NR_ZONES; zone++) {
|
||||||
* If the section is smallest section in the pgdat, it need
|
unsigned long zone_end_pfn = zone->zone_start_pfn +
|
||||||
* shrink pgdat->node_start_pfn and pgdat->node_spanned_pages.
|
zone->spanned_pages;
|
||||||
* In this case, we find second smallest valid mem_section
|
|
||||||
* for shrinking zone.
|
/* No need to lock the zones, they can't change. */
|
||||||
*/
|
if (zone_end_pfn > node_end_pfn)
|
||||||
pfn = find_smallest_section_pfn(nid, NULL, end_pfn,
|
node_end_pfn = zone_end_pfn;
|
||||||
pgdat_end_pfn);
|
if (zone->zone_start_pfn < node_start_pfn)
|
||||||
if (pfn) {
|
node_start_pfn = zone->zone_start_pfn;
|
||||||
pgdat->node_start_pfn = pfn;
|
|
||||||
pgdat->node_spanned_pages = pgdat_end_pfn - pfn;
|
|
||||||
}
|
|
||||||
} else if (pgdat_end_pfn == end_pfn) {
|
|
||||||
/*
|
|
||||||
* If the section is biggest section in the pgdat, it need
|
|
||||||
* shrink pgdat->node_spanned_pages.
|
|
||||||
* In this case, we find second biggest valid mem_section for
|
|
||||||
* shrinking zone.
|
|
||||||
*/
|
|
||||||
pfn = find_biggest_section_pfn(nid, NULL, pgdat_start_pfn,
|
|
||||||
start_pfn);
|
|
||||||
if (pfn)
|
|
||||||
pgdat->node_spanned_pages = pfn - pgdat_start_pfn + 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
pgdat->node_start_pfn = node_start_pfn;
|
||||||
* If the section is not biggest or smallest mem_section in the pgdat,
|
pgdat->node_spanned_pages = node_end_pfn - node_start_pfn;
|
||||||
* it only creates a hole in the pgdat. So in this case, we need not
|
|
||||||
* change the pgdat.
|
|
||||||
* But perhaps, the pgdat has only hole data. Thus it check the pgdat
|
|
||||||
* has only hole or not.
|
|
||||||
*/
|
|
||||||
pfn = pgdat_start_pfn;
|
|
||||||
for (; pfn < pgdat_end_pfn; pfn += PAGES_PER_SUBSECTION) {
|
|
||||||
if (unlikely(!pfn_valid(pfn)))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (pfn_to_nid(pfn) != nid)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* Skip range to be removed */
|
|
||||||
if (pfn >= start_pfn && pfn < end_pfn)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* If we find valid section, we have nothing to do */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The pgdat has no valid section */
|
|
||||||
pgdat->node_start_pfn = 0;
|
|
||||||
pgdat->node_spanned_pages = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __remove_zone(struct zone *zone, unsigned long start_pfn,
|
static void __remove_zone(struct zone *zone, unsigned long start_pfn,
|
||||||
@ -507,7 +465,7 @@ static void __remove_zone(struct zone *zone, unsigned long start_pfn,
|
|||||||
|
|
||||||
pgdat_resize_lock(zone->zone_pgdat, &flags);
|
pgdat_resize_lock(zone->zone_pgdat, &flags);
|
||||||
shrink_zone_span(zone, start_pfn, start_pfn + nr_pages);
|
shrink_zone_span(zone, start_pfn, start_pfn + nr_pages);
|
||||||
shrink_pgdat_span(pgdat, start_pfn, start_pfn + nr_pages);
|
update_pgdat_span(pgdat);
|
||||||
pgdat_resize_unlock(zone->zone_pgdat, &flags);
|
pgdat_resize_unlock(zone->zone_pgdat, &flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,6 +103,7 @@ static void dev_pagemap_cleanup(struct dev_pagemap *pgmap)
|
|||||||
void memunmap_pages(struct dev_pagemap *pgmap)
|
void memunmap_pages(struct dev_pagemap *pgmap)
|
||||||
{
|
{
|
||||||
struct resource *res = &pgmap->res;
|
struct resource *res = &pgmap->res;
|
||||||
|
struct page *first_page;
|
||||||
unsigned long pfn;
|
unsigned long pfn;
|
||||||
int nid;
|
int nid;
|
||||||
|
|
||||||
@ -111,14 +112,16 @@ void memunmap_pages(struct dev_pagemap *pgmap)
|
|||||||
put_page(pfn_to_page(pfn));
|
put_page(pfn_to_page(pfn));
|
||||||
dev_pagemap_cleanup(pgmap);
|
dev_pagemap_cleanup(pgmap);
|
||||||
|
|
||||||
|
/* make sure to access a memmap that was actually initialized */
|
||||||
|
first_page = pfn_to_page(pfn_first(pgmap));
|
||||||
|
|
||||||
/* pages are dead and unused, undo the arch mapping */
|
/* pages are dead and unused, undo the arch mapping */
|
||||||
nid = page_to_nid(pfn_to_page(PHYS_PFN(res->start)));
|
nid = page_to_nid(first_page);
|
||||||
|
|
||||||
mem_hotplug_begin();
|
mem_hotplug_begin();
|
||||||
if (pgmap->type == MEMORY_DEVICE_PRIVATE) {
|
if (pgmap->type == MEMORY_DEVICE_PRIVATE) {
|
||||||
pfn = PHYS_PFN(res->start);
|
__remove_pages(page_zone(first_page), PHYS_PFN(res->start),
|
||||||
__remove_pages(page_zone(pfn_to_page(pfn)), pfn,
|
PHYS_PFN(resource_size(res)), NULL);
|
||||||
PHYS_PFN(resource_size(res)), NULL);
|
|
||||||
} else {
|
} else {
|
||||||
arch_remove_memory(nid, res->start, resource_size(res),
|
arch_remove_memory(nid, res->start, resource_size(res),
|
||||||
pgmap_altmap(pgmap));
|
pgmap_altmap(pgmap));
|
||||||
|
@ -271,7 +271,8 @@ void pagetypeinfo_showmixedcount_print(struct seq_file *m,
|
|||||||
* not matter as the mixed block count will still be correct
|
* not matter as the mixed block count will still be correct
|
||||||
*/
|
*/
|
||||||
for (; pfn < end_pfn; ) {
|
for (; pfn < end_pfn; ) {
|
||||||
if (!pfn_valid(pfn)) {
|
page = pfn_to_online_page(pfn);
|
||||||
|
if (!page) {
|
||||||
pfn = ALIGN(pfn + 1, MAX_ORDER_NR_PAGES);
|
pfn = ALIGN(pfn + 1, MAX_ORDER_NR_PAGES);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -279,13 +280,13 @@ void pagetypeinfo_showmixedcount_print(struct seq_file *m,
|
|||||||
block_end_pfn = ALIGN(pfn + 1, pageblock_nr_pages);
|
block_end_pfn = ALIGN(pfn + 1, pageblock_nr_pages);
|
||||||
block_end_pfn = min(block_end_pfn, end_pfn);
|
block_end_pfn = min(block_end_pfn, end_pfn);
|
||||||
|
|
||||||
page = pfn_to_page(pfn);
|
|
||||||
pageblock_mt = get_pageblock_migratetype(page);
|
pageblock_mt = get_pageblock_migratetype(page);
|
||||||
|
|
||||||
for (; pfn < block_end_pfn; pfn++) {
|
for (; pfn < block_end_pfn; pfn++) {
|
||||||
if (!pfn_valid_within(pfn))
|
if (!pfn_valid_within(pfn))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
/* The pageblock is online, no need to recheck. */
|
||||||
page = pfn_to_page(pfn);
|
page = pfn_to_page(pfn);
|
||||||
|
|
||||||
if (page_zone(page) != zone)
|
if (page_zone(page) != zone)
|
||||||
|
@ -61,6 +61,7 @@
|
|||||||
#include <linux/mmu_notifier.h>
|
#include <linux/mmu_notifier.h>
|
||||||
#include <linux/migrate.h>
|
#include <linux/migrate.h>
|
||||||
#include <linux/hugetlb.h>
|
#include <linux/hugetlb.h>
|
||||||
|
#include <linux/huge_mm.h>
|
||||||
#include <linux/backing-dev.h>
|
#include <linux/backing-dev.h>
|
||||||
#include <linux/page_idle.h>
|
#include <linux/page_idle.h>
|
||||||
#include <linux/memremap.h>
|
#include <linux/memremap.h>
|
||||||
|
@ -178,10 +178,13 @@ static int init_memcg_params(struct kmem_cache *s,
|
|||||||
|
|
||||||
static void destroy_memcg_params(struct kmem_cache *s)
|
static void destroy_memcg_params(struct kmem_cache *s)
|
||||||
{
|
{
|
||||||
if (is_root_cache(s))
|
if (is_root_cache(s)) {
|
||||||
kvfree(rcu_access_pointer(s->memcg_params.memcg_caches));
|
kvfree(rcu_access_pointer(s->memcg_params.memcg_caches));
|
||||||
else
|
} else {
|
||||||
|
mem_cgroup_put(s->memcg_params.memcg);
|
||||||
|
WRITE_ONCE(s->memcg_params.memcg, NULL);
|
||||||
percpu_ref_exit(&s->memcg_params.refcnt);
|
percpu_ref_exit(&s->memcg_params.refcnt);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void free_memcg_params(struct rcu_head *rcu)
|
static void free_memcg_params(struct rcu_head *rcu)
|
||||||
@ -253,8 +256,6 @@ static void memcg_unlink_cache(struct kmem_cache *s)
|
|||||||
} else {
|
} else {
|
||||||
list_del(&s->memcg_params.children_node);
|
list_del(&s->memcg_params.children_node);
|
||||||
list_del(&s->memcg_params.kmem_caches_node);
|
list_del(&s->memcg_params.kmem_caches_node);
|
||||||
mem_cgroup_put(s->memcg_params.memcg);
|
|
||||||
WRITE_ONCE(s->memcg_params.memcg, NULL);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
@ -592,6 +592,16 @@ unsigned long invalidate_mapping_pages(struct address_space *mapping,
|
|||||||
unlock_page(page);
|
unlock_page(page);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Take a pin outside pagevec */
|
||||||
|
get_page(page);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Drop extra pins before trying to invalidate
|
||||||
|
* the huge page.
|
||||||
|
*/
|
||||||
|
pagevec_remove_exceptionals(&pvec);
|
||||||
|
pagevec_release(&pvec);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = invalidate_inode_page(page);
|
ret = invalidate_inode_page(page);
|
||||||
@ -602,6 +612,8 @@ unsigned long invalidate_mapping_pages(struct address_space *mapping,
|
|||||||
*/
|
*/
|
||||||
if (!ret)
|
if (!ret)
|
||||||
deactivate_file_page(page);
|
deactivate_file_page(page);
|
||||||
|
if (PageTransHuge(page))
|
||||||
|
put_page(page);
|
||||||
count += ret;
|
count += ret;
|
||||||
}
|
}
|
||||||
pagevec_remove_exceptionals(&pvec);
|
pagevec_remove_exceptionals(&pvec);
|
||||||
|
14
mm/vmscan.c
14
mm/vmscan.c
@ -351,12 +351,13 @@ unsigned long zone_reclaimable_pages(struct zone *zone)
|
|||||||
*/
|
*/
|
||||||
unsigned long lruvec_lru_size(struct lruvec *lruvec, enum lru_list lru, int zone_idx)
|
unsigned long lruvec_lru_size(struct lruvec *lruvec, enum lru_list lru, int zone_idx)
|
||||||
{
|
{
|
||||||
unsigned long lru_size;
|
unsigned long lru_size = 0;
|
||||||
int zid;
|
int zid;
|
||||||
|
|
||||||
if (!mem_cgroup_disabled())
|
if (!mem_cgroup_disabled()) {
|
||||||
lru_size = lruvec_page_state_local(lruvec, NR_LRU_BASE + lru);
|
for (zid = 0; zid < MAX_NR_ZONES; zid++)
|
||||||
else
|
lru_size += mem_cgroup_get_zone_lru_size(lruvec, lru, zid);
|
||||||
|
} else
|
||||||
lru_size = node_page_state(lruvec_pgdat(lruvec), NR_LRU_BASE + lru);
|
lru_size = node_page_state(lruvec_pgdat(lruvec), NR_LRU_BASE + lru);
|
||||||
|
|
||||||
for (zid = zone_idx + 1; zid < MAX_NR_ZONES; zid++) {
|
for (zid = zone_idx + 1; zid < MAX_NR_ZONES; zid++) {
|
||||||
@ -932,10 +933,7 @@ static int __remove_mapping(struct address_space *mapping, struct page *page,
|
|||||||
* Note that if SetPageDirty is always performed via set_page_dirty,
|
* Note that if SetPageDirty is always performed via set_page_dirty,
|
||||||
* and thus under the i_pages lock, then this ordering is not required.
|
* and thus under the i_pages lock, then this ordering is not required.
|
||||||
*/
|
*/
|
||||||
if (unlikely(PageTransHuge(page)) && PageSwapCache(page))
|
refcount = 1 + compound_nr(page);
|
||||||
refcount = 1 + HPAGE_PMD_NR;
|
|
||||||
else
|
|
||||||
refcount = 2;
|
|
||||||
if (!page_ref_freeze(page, refcount))
|
if (!page_ref_freeze(page, refcount))
|
||||||
goto cannot_free;
|
goto cannot_free;
|
||||||
/* note: atomic_cmpxchg in page_ref_freeze provides the smp_rmb */
|
/* note: atomic_cmpxchg in page_ref_freeze provides the smp_rmb */
|
||||||
|
@ -16,6 +16,8 @@ import sys
|
|||||||
|
|
||||||
from linux import utils
|
from linux import utils
|
||||||
|
|
||||||
|
printk_log_type = utils.CachedType("struct printk_log")
|
||||||
|
|
||||||
|
|
||||||
class LxDmesg(gdb.Command):
|
class LxDmesg(gdb.Command):
|
||||||
"""Print Linux kernel log buffer."""
|
"""Print Linux kernel log buffer."""
|
||||||
@ -42,9 +44,14 @@ class LxDmesg(gdb.Command):
|
|||||||
b = utils.read_memoryview(inf, log_buf_addr, log_next_idx)
|
b = utils.read_memoryview(inf, log_buf_addr, log_next_idx)
|
||||||
log_buf = a.tobytes() + b.tobytes()
|
log_buf = a.tobytes() + b.tobytes()
|
||||||
|
|
||||||
|
length_offset = printk_log_type.get_type()['len'].bitpos // 8
|
||||||
|
text_len_offset = printk_log_type.get_type()['text_len'].bitpos // 8
|
||||||
|
time_stamp_offset = printk_log_type.get_type()['ts_nsec'].bitpos // 8
|
||||||
|
text_offset = printk_log_type.get_type().sizeof
|
||||||
|
|
||||||
pos = 0
|
pos = 0
|
||||||
while pos < log_buf.__len__():
|
while pos < log_buf.__len__():
|
||||||
length = utils.read_u16(log_buf[pos + 8:pos + 10])
|
length = utils.read_u16(log_buf, pos + length_offset)
|
||||||
if length == 0:
|
if length == 0:
|
||||||
if log_buf_2nd_half == -1:
|
if log_buf_2nd_half == -1:
|
||||||
gdb.write("Corrupted log buffer!\n")
|
gdb.write("Corrupted log buffer!\n")
|
||||||
@ -52,10 +59,11 @@ class LxDmesg(gdb.Command):
|
|||||||
pos = log_buf_2nd_half
|
pos = log_buf_2nd_half
|
||||||
continue
|
continue
|
||||||
|
|
||||||
text_len = utils.read_u16(log_buf[pos + 10:pos + 12])
|
text_len = utils.read_u16(log_buf, pos + text_len_offset)
|
||||||
text = log_buf[pos + 16:pos + 16 + text_len].decode(
|
text_start = pos + text_offset
|
||||||
|
text = log_buf[text_start:text_start + text_len].decode(
|
||||||
encoding='utf8', errors='replace')
|
encoding='utf8', errors='replace')
|
||||||
time_stamp = utils.read_u64(log_buf[pos:pos + 8])
|
time_stamp = utils.read_u64(log_buf, pos + time_stamp_offset)
|
||||||
|
|
||||||
for line in text.splitlines():
|
for line in text.splitlines():
|
||||||
msg = u"[{time:12.6f}] {line}\n".format(
|
msg = u"[{time:12.6f}] {line}\n".format(
|
||||||
|
@ -15,7 +15,7 @@ import gdb
|
|||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from linux import modules
|
from linux import modules, utils
|
||||||
|
|
||||||
|
|
||||||
if hasattr(gdb, 'Breakpoint'):
|
if hasattr(gdb, 'Breakpoint'):
|
||||||
@ -116,6 +116,12 @@ lx-symbols command."""
|
|||||||
module_file = self._get_module_file(module_name)
|
module_file = self._get_module_file(module_name)
|
||||||
|
|
||||||
if module_file:
|
if module_file:
|
||||||
|
if utils.is_target_arch('s390'):
|
||||||
|
# Module text is preceded by PLT stubs on s390.
|
||||||
|
module_arch = module['arch']
|
||||||
|
plt_offset = int(module_arch['plt_offset'])
|
||||||
|
plt_size = int(module_arch['plt_size'])
|
||||||
|
module_addr = hex(int(module_addr, 0) + plt_offset + plt_size)
|
||||||
gdb.write("loading @{addr}: {filename}\n".format(
|
gdb.write("loading @{addr}: {filename}\n".format(
|
||||||
addr=module_addr, filename=module_file))
|
addr=module_addr, filename=module_file))
|
||||||
cmdline = "add-symbol-file {filename} {addr}{sections}".format(
|
cmdline = "add-symbol-file {filename} {addr}{sections}".format(
|
||||||
|
@ -92,15 +92,16 @@ def read_memoryview(inf, start, length):
|
|||||||
return memoryview(inf.read_memory(start, length))
|
return memoryview(inf.read_memory(start, length))
|
||||||
|
|
||||||
|
|
||||||
def read_u16(buffer):
|
def read_u16(buffer, offset):
|
||||||
|
buffer_val = buffer[offset:offset + 2]
|
||||||
value = [0, 0]
|
value = [0, 0]
|
||||||
|
|
||||||
if type(buffer[0]) is str:
|
if type(buffer_val[0]) is str:
|
||||||
value[0] = ord(buffer[0])
|
value[0] = ord(buffer_val[0])
|
||||||
value[1] = ord(buffer[1])
|
value[1] = ord(buffer_val[1])
|
||||||
else:
|
else:
|
||||||
value[0] = buffer[0]
|
value[0] = buffer_val[0]
|
||||||
value[1] = buffer[1]
|
value[1] = buffer_val[1]
|
||||||
|
|
||||||
if get_target_endianness() == LITTLE_ENDIAN:
|
if get_target_endianness() == LITTLE_ENDIAN:
|
||||||
return value[0] + (value[1] << 8)
|
return value[0] + (value[1] << 8)
|
||||||
@ -108,18 +109,18 @@ def read_u16(buffer):
|
|||||||
return value[1] + (value[0] << 8)
|
return value[1] + (value[0] << 8)
|
||||||
|
|
||||||
|
|
||||||
def read_u32(buffer):
|
def read_u32(buffer, offset):
|
||||||
if get_target_endianness() == LITTLE_ENDIAN:
|
if get_target_endianness() == LITTLE_ENDIAN:
|
||||||
return read_u16(buffer[0:2]) + (read_u16(buffer[2:4]) << 16)
|
return read_u16(buffer, offset) + (read_u16(buffer, offset + 2) << 16)
|
||||||
else:
|
else:
|
||||||
return read_u16(buffer[2:4]) + (read_u16(buffer[0:2]) << 16)
|
return read_u16(buffer, offset + 2) + (read_u16(buffer, offset) << 16)
|
||||||
|
|
||||||
|
|
||||||
def read_u64(buffer):
|
def read_u64(buffer, offset):
|
||||||
if get_target_endianness() == LITTLE_ENDIAN:
|
if get_target_endianness() == LITTLE_ENDIAN:
|
||||||
return read_u32(buffer[0:4]) + (read_u32(buffer[4:8]) << 32)
|
return read_u32(buffer, offset) + (read_u32(buffer, offset + 4) << 32)
|
||||||
else:
|
else:
|
||||||
return read_u32(buffer[4:8]) + (read_u32(buffer[0:4]) << 32)
|
return read_u32(buffer, offset + 4) + (read_u32(buffer, offset) << 32)
|
||||||
|
|
||||||
|
|
||||||
target_arch = None
|
target_arch = None
|
||||||
|
@ -37,7 +37,7 @@ int main(int argc, char **argv)
|
|||||||
char *file = "/dev/zero";
|
char *file = "/dev/zero";
|
||||||
char *p;
|
char *p;
|
||||||
|
|
||||||
while ((opt = getopt(argc, argv, "m:r:n:f:tTLUSH")) != -1) {
|
while ((opt = getopt(argc, argv, "m:r:n:f:tTLUwSH")) != -1) {
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 'm':
|
case 'm':
|
||||||
size = atoi(optarg) * MB;
|
size = atoi(optarg) * MB;
|
||||||
|
Loading…
Reference in New Issue
Block a user