Commit 2844a487 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'akpm' (Fixes from Andrew)

Merge misc fixes from Andrew Morton:
 "8 fixes"

* emailed patches from Andrew Morton <akpm@linux-foundation.org>: (8 patches)
  futex: avoid wake_futex() for a PI futex_q
  watchdog: using u64 in get_sample_period()
  writeback: put unused inodes to LRU after writeback completion
  mm: vmscan: check for fatal signals iff the process was throttled
  Revert "mm: remove __GFP_NO_KSWAPD"
  proc: check vma->vm_file before dereferencing
  UAPI: strip the _UAPI prefix from header guards during header installation
  include/linux/bug.h: fix sparse warning related to BUILD_BUG_ON_INVALID
parents 5687100a aa10990e
...@@ -1077,7 +1077,8 @@ EXPORT_SYMBOL_GPL(mtd_writev); ...@@ -1077,7 +1077,8 @@ EXPORT_SYMBOL_GPL(mtd_writev);
* until the request succeeds or until the allocation size falls below * until the request succeeds or until the allocation size falls below
* the system page size. This attempts to make sure it does not adversely * the system page size. This attempts to make sure it does not adversely
* impact system performance, so when allocating more than one page, we * impact system performance, so when allocating more than one page, we
* ask the memory allocator to avoid re-trying. * ask the memory allocator to avoid re-trying, swapping, writing back
* or performing I/O.
* *
* Note, this function also makes sure that the allocated buffer is aligned to * Note, this function also makes sure that the allocated buffer is aligned to
* the MTD device's min. I/O unit, i.e. the "mtd->writesize" value. * the MTD device's min. I/O unit, i.e. the "mtd->writesize" value.
...@@ -1091,7 +1092,8 @@ EXPORT_SYMBOL_GPL(mtd_writev); ...@@ -1091,7 +1092,8 @@ EXPORT_SYMBOL_GPL(mtd_writev);
*/ */
void *mtd_kmalloc_up_to(const struct mtd_info *mtd, size_t *size) void *mtd_kmalloc_up_to(const struct mtd_info *mtd, size_t *size)
{ {
gfp_t flags = __GFP_NOWARN | __GFP_WAIT | __GFP_NORETRY; gfp_t flags = __GFP_NOWARN | __GFP_WAIT |
__GFP_NORETRY | __GFP_NO_KSWAPD;
size_t min_alloc = max_t(size_t, mtd->writesize, PAGE_SIZE); size_t min_alloc = max_t(size_t, mtd->writesize, PAGE_SIZE);
void *kbuf; void *kbuf;
......
...@@ -228,6 +228,8 @@ static void requeue_io(struct inode *inode, struct bdi_writeback *wb) ...@@ -228,6 +228,8 @@ static void requeue_io(struct inode *inode, struct bdi_writeback *wb)
static void inode_sync_complete(struct inode *inode) static void inode_sync_complete(struct inode *inode)
{ {
inode->i_state &= ~I_SYNC; inode->i_state &= ~I_SYNC;
/* If inode is clean an unused, put it into LRU now... */
inode_add_lru(inode);
/* Waiters must see I_SYNC cleared before being woken up */ /* Waiters must see I_SYNC cleared before being woken up */
smp_mb(); smp_mb();
wake_up_bit(&inode->i_state, __I_SYNC); wake_up_bit(&inode->i_state, __I_SYNC);
......
...@@ -408,6 +408,19 @@ static void inode_lru_list_add(struct inode *inode) ...@@ -408,6 +408,19 @@ static void inode_lru_list_add(struct inode *inode)
spin_unlock(&inode->i_sb->s_inode_lru_lock); spin_unlock(&inode->i_sb->s_inode_lru_lock);
} }
/*
* Add inode to LRU if needed (inode is unused and clean).
*
* Needs inode->i_lock held.
*/
void inode_add_lru(struct inode *inode)
{
if (!(inode->i_state & (I_DIRTY | I_SYNC | I_FREEING | I_WILL_FREE)) &&
!atomic_read(&inode->i_count) && inode->i_sb->s_flags & MS_ACTIVE)
inode_lru_list_add(inode);
}
static void inode_lru_list_del(struct inode *inode) static void inode_lru_list_del(struct inode *inode)
{ {
spin_lock(&inode->i_sb->s_inode_lru_lock); spin_lock(&inode->i_sb->s_inode_lru_lock);
...@@ -1390,8 +1403,7 @@ static void iput_final(struct inode *inode) ...@@ -1390,8 +1403,7 @@ static void iput_final(struct inode *inode)
if (!drop && (sb->s_flags & MS_ACTIVE)) { if (!drop && (sb->s_flags & MS_ACTIVE)) {
inode->i_state |= I_REFERENCED; inode->i_state |= I_REFERENCED;
if (!(inode->i_state & (I_DIRTY|I_SYNC))) inode_add_lru(inode);
inode_lru_list_add(inode);
spin_unlock(&inode->i_lock); spin_unlock(&inode->i_lock);
return; return;
} }
......
...@@ -110,6 +110,7 @@ extern int open_check_o_direct(struct file *f); ...@@ -110,6 +110,7 @@ extern int open_check_o_direct(struct file *f);
* inode.c * inode.c
*/ */
extern spinlock_t inode_sb_list_lock; extern spinlock_t inode_sb_list_lock;
extern void inode_add_lru(struct inode *inode);
/* /*
* fs-writeback.c * fs-writeback.c
......
...@@ -1877,6 +1877,7 @@ static struct dentry *proc_map_files_lookup(struct inode *dir, ...@@ -1877,6 +1877,7 @@ static struct dentry *proc_map_files_lookup(struct inode *dir,
if (!vma) if (!vma)
goto out_no_vma; goto out_no_vma;
if (vma->vm_file)
result = proc_map_files_instantiate(dir, dentry, task, result = proc_map_files_instantiate(dir, dentry, task,
(void *)(unsigned long)vma->vm_file->f_mode); (void *)(unsigned long)vma->vm_file->f_mode);
......
...@@ -15,6 +15,7 @@ struct pt_regs; ...@@ -15,6 +15,7 @@ struct pt_regs;
#define BUILD_BUG_ON_NOT_POWER_OF_2(n) #define BUILD_BUG_ON_NOT_POWER_OF_2(n)
#define BUILD_BUG_ON_ZERO(e) (0) #define BUILD_BUG_ON_ZERO(e) (0)
#define BUILD_BUG_ON_NULL(e) ((void*)0) #define BUILD_BUG_ON_NULL(e) ((void*)0)
#define BUILD_BUG_ON_INVALID(e) (0)
#define BUILD_BUG_ON(condition) #define BUILD_BUG_ON(condition)
#define BUILD_BUG() (0) #define BUILD_BUG() (0)
#else /* __CHECKER__ */ #else /* __CHECKER__ */
......
...@@ -31,6 +31,7 @@ struct vm_area_struct; ...@@ -31,6 +31,7 @@ struct vm_area_struct;
#define ___GFP_THISNODE 0x40000u #define ___GFP_THISNODE 0x40000u
#define ___GFP_RECLAIMABLE 0x80000u #define ___GFP_RECLAIMABLE 0x80000u
#define ___GFP_NOTRACK 0x200000u #define ___GFP_NOTRACK 0x200000u
#define ___GFP_NO_KSWAPD 0x400000u
#define ___GFP_OTHER_NODE 0x800000u #define ___GFP_OTHER_NODE 0x800000u
#define ___GFP_WRITE 0x1000000u #define ___GFP_WRITE 0x1000000u
...@@ -85,6 +86,7 @@ struct vm_area_struct; ...@@ -85,6 +86,7 @@ struct vm_area_struct;
#define __GFP_RECLAIMABLE ((__force gfp_t)___GFP_RECLAIMABLE) /* Page is reclaimable */ #define __GFP_RECLAIMABLE ((__force gfp_t)___GFP_RECLAIMABLE) /* Page is reclaimable */
#define __GFP_NOTRACK ((__force gfp_t)___GFP_NOTRACK) /* Don't track with kmemcheck */ #define __GFP_NOTRACK ((__force gfp_t)___GFP_NOTRACK) /* Don't track with kmemcheck */
#define __GFP_NO_KSWAPD ((__force gfp_t)___GFP_NO_KSWAPD)
#define __GFP_OTHER_NODE ((__force gfp_t)___GFP_OTHER_NODE) /* On behalf of other node */ #define __GFP_OTHER_NODE ((__force gfp_t)___GFP_OTHER_NODE) /* On behalf of other node */
#define __GFP_WRITE ((__force gfp_t)___GFP_WRITE) /* Allocator intends to dirty page */ #define __GFP_WRITE ((__force gfp_t)___GFP_WRITE) /* Allocator intends to dirty page */
...@@ -114,7 +116,8 @@ struct vm_area_struct; ...@@ -114,7 +116,8 @@ struct vm_area_struct;
__GFP_MOVABLE) __GFP_MOVABLE)
#define GFP_IOFS (__GFP_IO | __GFP_FS) #define GFP_IOFS (__GFP_IO | __GFP_FS)
#define GFP_TRANSHUGE (GFP_HIGHUSER_MOVABLE | __GFP_COMP | \ #define GFP_TRANSHUGE (GFP_HIGHUSER_MOVABLE | __GFP_COMP | \
__GFP_NOMEMALLOC | __GFP_NORETRY | __GFP_NOWARN) __GFP_NOMEMALLOC | __GFP_NORETRY | __GFP_NOWARN | \
__GFP_NO_KSWAPD)
#ifdef CONFIG_NUMA #ifdef CONFIG_NUMA
#define GFP_THISNODE (__GFP_THISNODE | __GFP_NOWARN | __GFP_NORETRY) #define GFP_THISNODE (__GFP_THISNODE | __GFP_NOWARN | __GFP_NORETRY)
......
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
{(unsigned long)__GFP_RECLAIMABLE, "GFP_RECLAIMABLE"}, \ {(unsigned long)__GFP_RECLAIMABLE, "GFP_RECLAIMABLE"}, \
{(unsigned long)__GFP_MOVABLE, "GFP_MOVABLE"}, \ {(unsigned long)__GFP_MOVABLE, "GFP_MOVABLE"}, \
{(unsigned long)__GFP_NOTRACK, "GFP_NOTRACK"}, \ {(unsigned long)__GFP_NOTRACK, "GFP_NOTRACK"}, \
{(unsigned long)__GFP_NO_KSWAPD, "GFP_NO_KSWAPD"}, \
{(unsigned long)__GFP_OTHER_NODE, "GFP_OTHER_NODE"} \ {(unsigned long)__GFP_OTHER_NODE, "GFP_OTHER_NODE"} \
) : "GFP_NOWAIT" ) : "GFP_NOWAIT"
...@@ -843,6 +843,9 @@ static void wake_futex(struct futex_q *q) ...@@ -843,6 +843,9 @@ static void wake_futex(struct futex_q *q)
{ {
struct task_struct *p = q->task; struct task_struct *p = q->task;
if (WARN(q->pi_state || q->rt_waiter, "refusing to wake PI futex\n"))
return;
/* /*
* We set q->lock_ptr = NULL _before_ we wake up the task. If * We set q->lock_ptr = NULL _before_ we wake up the task. If
* a non-futex wake up happens on another CPU then the task * a non-futex wake up happens on another CPU then the task
...@@ -1078,6 +1081,10 @@ futex_wake_op(u32 __user *uaddr1, unsigned int flags, u32 __user *uaddr2, ...@@ -1078,6 +1081,10 @@ futex_wake_op(u32 __user *uaddr1, unsigned int flags, u32 __user *uaddr2,
plist_for_each_entry_safe(this, next, head, list) { plist_for_each_entry_safe(this, next, head, list) {
if (match_futex (&this->key, &key1)) { if (match_futex (&this->key, &key1)) {
if (this->pi_state || this->rt_waiter) {
ret = -EINVAL;
goto out_unlock;
}
wake_futex(this); wake_futex(this);
if (++ret >= nr_wake) if (++ret >= nr_wake)
break; break;
...@@ -1090,6 +1097,10 @@ futex_wake_op(u32 __user *uaddr1, unsigned int flags, u32 __user *uaddr2, ...@@ -1090,6 +1097,10 @@ futex_wake_op(u32 __user *uaddr1, unsigned int flags, u32 __user *uaddr2,
op_ret = 0; op_ret = 0;
plist_for_each_entry_safe(this, next, head, list) { plist_for_each_entry_safe(this, next, head, list) {
if (match_futex (&this->key, &key2)) { if (match_futex (&this->key, &key2)) {
if (this->pi_state || this->rt_waiter) {
ret = -EINVAL;
goto out_unlock;
}
wake_futex(this); wake_futex(this);
if (++op_ret >= nr_wake2) if (++op_ret >= nr_wake2)
break; break;
...@@ -1098,6 +1109,7 @@ futex_wake_op(u32 __user *uaddr1, unsigned int flags, u32 __user *uaddr2, ...@@ -1098,6 +1109,7 @@ futex_wake_op(u32 __user *uaddr1, unsigned int flags, u32 __user *uaddr2,
ret += op_ret; ret += op_ret;
} }
out_unlock:
double_unlock_hb(hb1, hb2); double_unlock_hb(hb1, hb2);
out_put_keys: out_put_keys:
put_futex_key(&key2); put_futex_key(&key2);
...@@ -1387,9 +1399,13 @@ static int futex_requeue(u32 __user *uaddr1, unsigned int flags, ...@@ -1387,9 +1399,13 @@ static int futex_requeue(u32 __user *uaddr1, unsigned int flags,
/* /*
* FUTEX_WAIT_REQEUE_PI and FUTEX_CMP_REQUEUE_PI should always * FUTEX_WAIT_REQEUE_PI and FUTEX_CMP_REQUEUE_PI should always
* be paired with each other and no other futex ops. * be paired with each other and no other futex ops.
*
* We should never be requeueing a futex_q with a pi_state,
* which is awaiting a futex_unlock_pi().
*/ */
if ((requeue_pi && !this->rt_waiter) || if ((requeue_pi && !this->rt_waiter) ||
(!requeue_pi && this->rt_waiter)) { (!requeue_pi && this->rt_waiter) ||
this->pi_state) {
ret = -EINVAL; ret = -EINVAL;
break; break;
} }
......
...@@ -116,7 +116,7 @@ static unsigned long get_timestamp(int this_cpu) ...@@ -116,7 +116,7 @@ static unsigned long get_timestamp(int this_cpu)
return cpu_clock(this_cpu) >> 30LL; /* 2^30 ~= 10^9 */ return cpu_clock(this_cpu) >> 30LL; /* 2^30 ~= 10^9 */
} }
static unsigned long get_sample_period(void) static u64 get_sample_period(void)
{ {
/* /*
* convert watchdog_thresh from seconds to ns * convert watchdog_thresh from seconds to ns
...@@ -125,7 +125,7 @@ static unsigned long get_sample_period(void) ...@@ -125,7 +125,7 @@ static unsigned long get_sample_period(void)
* and hard thresholds) to increment before the * and hard thresholds) to increment before the
* hardlockup detector generates a warning * hardlockup detector generates a warning
*/ */
return get_softlockup_thresh() * (NSEC_PER_SEC / 5); return get_softlockup_thresh() * ((u64)NSEC_PER_SEC / 5);
} }
/* Commands for resetting the watchdog */ /* Commands for resetting the watchdog */
......
...@@ -2416,6 +2416,7 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order, ...@@ -2416,6 +2416,7 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order,
goto nopage; goto nopage;
restart: restart:
if (!(gfp_mask & __GFP_NO_KSWAPD))
wake_all_kswapd(order, zonelist, high_zoneidx, wake_all_kswapd(order, zonelist, high_zoneidx,
zone_idx(preferred_zone)); zone_idx(preferred_zone));
...@@ -2494,7 +2495,7 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order, ...@@ -2494,7 +2495,7 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order,
* system then fail the allocation instead of entering direct reclaim. * system then fail the allocation instead of entering direct reclaim.
*/ */
if ((deferred_compaction || contended_compaction) && if ((deferred_compaction || contended_compaction) &&
(gfp_mask & (__GFP_MOVABLE|__GFP_REPEAT)) == __GFP_MOVABLE) (gfp_mask & __GFP_NO_KSWAPD))
goto nopage; goto nopage;
/* Try direct reclaim and then allocating */ /* Try direct reclaim and then allocating */
......
...@@ -2207,9 +2207,12 @@ static bool pfmemalloc_watermark_ok(pg_data_t *pgdat) ...@@ -2207,9 +2207,12 @@ static bool pfmemalloc_watermark_ok(pg_data_t *pgdat)
* Throttle direct reclaimers if backing storage is backed by the network * Throttle direct reclaimers if backing storage is backed by the network
* and the PFMEMALLOC reserve for the preferred node is getting dangerously * and the PFMEMALLOC reserve for the preferred node is getting dangerously
* depleted. kswapd will continue to make progress and wake the processes * depleted. kswapd will continue to make progress and wake the processes
* when the low watermark is reached * when the low watermark is reached.
*
* Returns true if a fatal signal was delivered during throttling. If this
* happens, the page allocator should not consider triggering the OOM killer.
*/ */
static void throttle_direct_reclaim(gfp_t gfp_mask, struct zonelist *zonelist, static bool throttle_direct_reclaim(gfp_t gfp_mask, struct zonelist *zonelist,
nodemask_t *nodemask) nodemask_t *nodemask)
{ {
struct zone *zone; struct zone *zone;
...@@ -2224,13 +2227,20 @@ static void throttle_direct_reclaim(gfp_t gfp_mask, struct zonelist *zonelist, ...@@ -2224,13 +2227,20 @@ static void throttle_direct_reclaim(gfp_t gfp_mask, struct zonelist *zonelist,
* processes to block on log_wait_commit(). * processes to block on log_wait_commit().
*/ */
if (current->flags & PF_KTHREAD) if (current->flags & PF_KTHREAD)
return; goto out;
/*
* If a fatal signal is pending, this process should not throttle.
* It should return quickly so it can exit and free its memory
*/
if (fatal_signal_pending(current))
goto out;
/* Check if the pfmemalloc reserves are ok */ /* Check if the pfmemalloc reserves are ok */
first_zones_zonelist(zonelist, high_zoneidx, NULL, &zone); first_zones_zonelist(zonelist, high_zoneidx, NULL, &zone);
pgdat = zone->zone_pgdat; pgdat = zone->zone_pgdat;
if (pfmemalloc_watermark_ok(pgdat)) if (pfmemalloc_watermark_ok(pgdat))
return; goto out;
/* Account for the throttling */ /* Account for the throttling */
count_vm_event(PGSCAN_DIRECT_THROTTLE); count_vm_event(PGSCAN_DIRECT_THROTTLE);
...@@ -2246,12 +2256,20 @@ static void throttle_direct_reclaim(gfp_t gfp_mask, struct zonelist *zonelist, ...@@ -2246,12 +2256,20 @@ static void throttle_direct_reclaim(gfp_t gfp_mask, struct zonelist *zonelist,
if (!(gfp_mask & __GFP_FS)) { if (!(gfp_mask & __GFP_FS)) {
wait_event_interruptible_timeout(pgdat->pfmemalloc_wait, wait_event_interruptible_timeout(pgdat->pfmemalloc_wait,
pfmemalloc_watermark_ok(pgdat), HZ); pfmemalloc_watermark_ok(pgdat), HZ);
return;
goto check_pending;
} }
/* Throttle until kswapd wakes the process */ /* Throttle until kswapd wakes the process */
wait_event_killable(zone->zone_pgdat->pfmemalloc_wait, wait_event_killable(zone->zone_pgdat->pfmemalloc_wait,
pfmemalloc_watermark_ok(pgdat)); pfmemalloc_watermark_ok(pgdat));
check_pending:
if (fatal_signal_pending(current))
return true;
out:
return false;
} }
unsigned long try_to_free_pages(struct zonelist *zonelist, int order, unsigned long try_to_free_pages(struct zonelist *zonelist, int order,
...@@ -2273,13 +2291,12 @@ unsigned long try_to_free_pages(struct zonelist *zonelist, int order, ...@@ -2273,13 +2291,12 @@ unsigned long try_to_free_pages(struct zonelist *zonelist, int order,
.gfp_mask = sc.gfp_mask, .gfp_mask = sc.gfp_mask,
}; };
throttle_direct_reclaim(gfp_mask, zonelist, nodemask);
/* /*
* Do not enter reclaim if fatal signal is pending. 1 is returned so * Do not enter reclaim if fatal signal was delivered while throttled.
* that the page allocator does not consider triggering OOM * 1 is returned so that the page allocator does not OOM kill at this
* point.
*/ */
if (fatal_signal_pending(current)) if (throttle_direct_reclaim(gfp_mask, zonelist, nodemask))
return 1; return 1;
trace_mm_vmscan_direct_reclaim_begin(order, trace_mm_vmscan_direct_reclaim_begin(order,
......
...@@ -42,6 +42,9 @@ foreach my $filename (@files) { ...@@ -42,6 +42,9 @@ foreach my $filename (@files) {
$line =~ s/(^|\s)(inline)\b/$1__$2__/g; $line =~ s/(^|\s)(inline)\b/$1__$2__/g;
$line =~ s/(^|\s)(asm)\b(\s|[(]|$)/$1__$2__$3/g; $line =~ s/(^|\s)(asm)\b(\s|[(]|$)/$1__$2__$3/g;
$line =~ s/(^|\s|[(])(volatile)\b(\s|[(]|$)/$1__$2__$3/g; $line =~ s/(^|\s|[(])(volatile)\b(\s|[(]|$)/$1__$2__$3/g;
$line =~ s/#ifndef _UAPI/#ifndef /;
$line =~ s/#define _UAPI/#define /;
$line =~ s!#endif /[*] _UAPI!#endif /* !;
printf {$out} "%s", $line; printf {$out} "%s", $line;
} }
close $out; close $out;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment