Revision df9576def004d2cd5beedc00cb6e8901427634b9 authored by Yang Shi on 03 August 2019, 04:48:37 UTC, committed by Linus Torvalds on 03 August 2019, 14:02:00 UTC
When running ltp's oom test with kmemleak enabled, the below warning was triggerred since kernel detects __GFP_NOFAIL & ~__GFP_DIRECT_RECLAIM is passed in: WARNING: CPU: 105 PID: 2138 at mm/page_alloc.c:4608 __alloc_pages_nodemask+0x1c31/0x1d50 Modules linked in: loop dax_pmem dax_pmem_core ip_tables x_tables xfs virtio_net net_failover virtio_blk failover ata_generic virtio_pci virtio_ring virtio libata CPU: 105 PID: 2138 Comm: oom01 Not tainted 5.2.0-next-20190710+ #7 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.10.2-0-g5f4c7b1-prebuilt.qemu-project.org 04/01/2014 RIP: 0010:__alloc_pages_nodemask+0x1c31/0x1d50 ... kmemleak_alloc+0x4e/0xb0 kmem_cache_alloc+0x2a7/0x3e0 mempool_alloc_slab+0x2d/0x40 mempool_alloc+0x118/0x2b0 bio_alloc_bioset+0x19d/0x350 get_swap_bio+0x80/0x230 __swap_writepage+0x5ff/0xb20 The mempool_alloc_slab() clears __GFP_DIRECT_RECLAIM, however kmemleak has __GFP_NOFAIL set all the time due to d9570ee3bd1d4f2 ("kmemleak: allow to coexist with fault injection"). But, it doesn't make any sense to have __GFP_NOFAIL and ~__GFP_DIRECT_RECLAIM specified at the same time. According to the discussion on the mailing list, the commit should be reverted for short term solution. Catalin Marinas would follow up with a better solution for longer term. The failure rate of kmemleak metadata allocation may increase in some circumstances, but this should be expected side effect. Link: http://lkml.kernel.org/r/1563299431-111710-1-git-send-email-yang.shi@linux.alibaba.com Fixes: d9570ee3bd1d4f2 ("kmemleak: allow to coexist with fault injection") Signed-off-by: Yang Shi <yang.shi@linux.alibaba.com> Suggested-by: Catalin Marinas <catalin.marinas@arm.com> Acked-by: Michal Hocko <mhocko@suse.com> Cc: Dmitry Vyukov <dvyukov@google.com> Cc: David Rientjes <rientjes@google.com> Cc: Matthew Wilcox <willy@infradead.org> Cc: Qian Cai <cai@lca.pw> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
1 parent 68d8681
time.h
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* time.h - NTFS time conversion functions. Part of the Linux-NTFS project.
*
* Copyright (c) 2001-2005 Anton Altaparmakov
*/
#ifndef _LINUX_NTFS_TIME_H
#define _LINUX_NTFS_TIME_H
#include <linux/time.h> /* For current_kernel_time(). */
#include <asm/div64.h> /* For do_div(). */
#include "endian.h"
#define NTFS_TIME_OFFSET ((s64)(369 * 365 + 89) * 24 * 3600 * 10000000)
/**
* utc2ntfs - convert Linux UTC time to NTFS time
* @ts: Linux UTC time to convert to NTFS time
*
* Convert the Linux UTC time @ts to its corresponding NTFS time and return
* that in little endian format.
*
* Linux stores time in a struct timespec64 consisting of a time64_t tv_sec
* and a long tv_nsec where tv_sec is the number of 1-second intervals since
* 1st January 1970, 00:00:00 UTC and tv_nsec is the number of 1-nano-second
* intervals since the value of tv_sec.
*
* NTFS uses Microsoft's standard time format which is stored in a s64 and is
* measured as the number of 100-nano-second intervals since 1st January 1601,
* 00:00:00 UTC.
*/
static inline sle64 utc2ntfs(const struct timespec64 ts)
{
/*
* Convert the seconds to 100ns intervals, add the nano-seconds
* converted to 100ns intervals, and then add the NTFS time offset.
*/
return cpu_to_sle64((s64)ts.tv_sec * 10000000 + ts.tv_nsec / 100 +
NTFS_TIME_OFFSET);
}
/**
* get_current_ntfs_time - get the current time in little endian NTFS format
*
* Get the current time from the Linux kernel, convert it to its corresponding
* NTFS time and return that in little endian format.
*/
static inline sle64 get_current_ntfs_time(void)
{
struct timespec64 ts;
ktime_get_coarse_real_ts64(&ts);
return utc2ntfs(ts);
}
/**
* ntfs2utc - convert NTFS time to Linux time
* @time: NTFS time (little endian) to convert to Linux UTC
*
* Convert the little endian NTFS time @time to its corresponding Linux UTC
* time and return that in cpu format.
*
* Linux stores time in a struct timespec64 consisting of a time64_t tv_sec
* and a long tv_nsec where tv_sec is the number of 1-second intervals since
* 1st January 1970, 00:00:00 UTC and tv_nsec is the number of 1-nano-second
* intervals since the value of tv_sec.
*
* NTFS uses Microsoft's standard time format which is stored in a s64 and is
* measured as the number of 100 nano-second intervals since 1st January 1601,
* 00:00:00 UTC.
*/
static inline struct timespec64 ntfs2utc(const sle64 time)
{
struct timespec64 ts;
/* Subtract the NTFS time offset. */
u64 t = (u64)(sle64_to_cpu(time) - NTFS_TIME_OFFSET);
/*
* Convert the time to 1-second intervals and the remainder to
* 1-nano-second intervals.
*/
ts.tv_nsec = do_div(t, 10000000) * 100;
ts.tv_sec = t;
return ts;
}
#endif /* _LINUX_NTFS_TIME_H */
![swh spinner](/static/img/swh-spinner.gif)
Computing file changes ...