Merge branch 'akpm' (Andrew's patch-bomb)
Merge random patches from Andrew Morton. * Merge emailed patches from Andrew Morton <akpm@linux-foundation.org>: (32 commits) memblock: free allocated memblock_reserved_regions later mm: sparse: fix usemap allocation above node descriptor section mm: sparse: fix section usemap placement calculation xtensa: fix incorrect memset shmem: cleanup shmem_add_to_page_cache shmem: fix negative rss in memcg memory.stat tmpfs: revert SEEK_DATA and SEEK_HOLE drivers/rtc/rtc-twl.c: fix threaded IRQ to use IRQF_ONESHOT fat: fix non-atomic NFS i_pos read MAINTAINERS: add OMAP CPUfreq driver to OMAP Power Management section sgi-xp: nested calls to spin_lock_irqsave() fs: ramfs: file-nommu: add SetPageUptodate() drivers/rtc/rtc-mxc.c: fix irq enabled interrupts warning mm/memory_hotplug.c: release memory resources if hotadd_new_pgdat() fails h8300/uaccess: add mising __clear_user() h8300/uaccess: remove assignment to __gu_val in unhandled case of get_user() h8300/time: add missing #include <asm/irq_regs.h> h8300/signal: fix typo "statis" h8300/pgtable: add missing #include <asm-generic/pgtable.h> drivers/rtc/rtc-ab8500.c: ensure correct probing of the AB8500 RTC when Device Tree is enabled ...
This commit is contained in:
commit
00c3e276c5
38 changed files with 197 additions and 247 deletions
|
@ -4857,6 +4857,7 @@ M: Kevin Hilman <khilman@ti.com>
|
||||||
L: linux-omap@vger.kernel.org
|
L: linux-omap@vger.kernel.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: arch/arm/*omap*/*pm*
|
F: arch/arm/*omap*/*pm*
|
||||||
|
F: drivers/cpufreq/omap-cpufreq.c
|
||||||
|
|
||||||
OMAP POWERDOMAIN/CLOCKDOMAIN SOC ADAPTATION LAYER SUPPORT
|
OMAP POWERDOMAIN/CLOCKDOMAIN SOC ADAPTATION LAYER SUPPORT
|
||||||
M: Rajendra Nayak <rnayak@ti.com>
|
M: Rajendra Nayak <rnayak@ti.com>
|
||||||
|
|
|
@ -70,4 +70,7 @@ extern int is_in_rom(unsigned long);
|
||||||
#define VMALLOC_END 0xffffffff
|
#define VMALLOC_END 0xffffffff
|
||||||
|
|
||||||
#define arch_enter_lazy_cpu_mode() do {} while (0)
|
#define arch_enter_lazy_cpu_mode() do {} while (0)
|
||||||
|
|
||||||
|
#include <asm-generic/pgtable.h>
|
||||||
|
|
||||||
#endif /* _H8300_PGTABLE_H */
|
#endif /* _H8300_PGTABLE_H */
|
||||||
|
|
|
@ -100,7 +100,6 @@ extern int __put_user_bad(void);
|
||||||
break; \
|
break; \
|
||||||
default: \
|
default: \
|
||||||
__gu_err = __get_user_bad(); \
|
__gu_err = __get_user_bad(); \
|
||||||
__gu_val = 0; \
|
|
||||||
break; \
|
break; \
|
||||||
} \
|
} \
|
||||||
(x) = __gu_val; \
|
(x) = __gu_val; \
|
||||||
|
@ -159,4 +158,6 @@ clear_user(void *to, unsigned long n)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define __clear_user clear_user
|
||||||
|
|
||||||
#endif /* _H8300_UACCESS_H */
|
#endif /* _H8300_UACCESS_H */
|
||||||
|
|
|
@ -447,7 +447,7 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
|
||||||
* want to handle. Thus you cannot kill init even with a SIGKILL even by
|
* want to handle. Thus you cannot kill init even with a SIGKILL even by
|
||||||
* mistake.
|
* mistake.
|
||||||
*/
|
*/
|
||||||
statis void do_signal(struct pt_regs *regs)
|
static void do_signal(struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
siginfo_t info;
|
siginfo_t info;
|
||||||
int signr;
|
int signr;
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include <linux/profile.h>
|
#include <linux/profile.h>
|
||||||
|
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
|
#include <asm/irq_regs.h>
|
||||||
#include <asm/timer.h>
|
#include <asm/timer.h>
|
||||||
|
|
||||||
#define TICK_SIZE (tick_nsec / 1000)
|
#define TICK_SIZE (tick_nsec / 1000)
|
||||||
|
|
|
@ -81,9 +81,6 @@ struct pt_regs {
|
||||||
#define PTRACE_GETFPREGS 14
|
#define PTRACE_GETFPREGS 14
|
||||||
#define PTRACE_SETFPREGS 15
|
#define PTRACE_SETFPREGS 15
|
||||||
|
|
||||||
/* options set using PTRACE_SETOPTIONS */
|
|
||||||
#define PTRACE_O_TRACESYSGOOD 0x00000001
|
|
||||||
|
|
||||||
#ifdef __KERNEL__
|
#ifdef __KERNEL__
|
||||||
|
|
||||||
#define user_mode(regs) (((regs)->epsw & EPSW_nSL) == EPSW_nSL)
|
#define user_mode(regs) (((regs)->epsw & EPSW_nSL) == EPSW_nSL)
|
||||||
|
|
|
@ -11,7 +11,6 @@
|
||||||
#ifndef _ASM_TIMEX_H
|
#ifndef _ASM_TIMEX_H
|
||||||
#define _ASM_TIMEX_H
|
#define _ASM_TIMEX_H
|
||||||
|
|
||||||
#include <asm/hardirq.h>
|
|
||||||
#include <unit/timex.h>
|
#include <unit/timex.h>
|
||||||
|
|
||||||
#define TICK_SIZE (tick_nsec / 1000)
|
#define TICK_SIZE (tick_nsec / 1000)
|
||||||
|
@ -30,16 +29,6 @@ static inline cycles_t get_cycles(void)
|
||||||
extern int init_clockevents(void);
|
extern int init_clockevents(void);
|
||||||
extern int init_clocksource(void);
|
extern int init_clocksource(void);
|
||||||
|
|
||||||
static inline void setup_jiffies_interrupt(int irq,
|
|
||||||
struct irqaction *action)
|
|
||||||
{
|
|
||||||
u16 tmp;
|
|
||||||
setup_irq(irq, action);
|
|
||||||
set_intr_level(irq, NUM2GxICR_LEVEL(CONFIG_TIMER_IRQ_LEVEL));
|
|
||||||
GxICR(irq) |= GxICR_ENABLE | GxICR_DETECT | GxICR_REQUEST;
|
|
||||||
tmp = GxICR(irq);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* __KERNEL__ */
|
#endif /* __KERNEL__ */
|
||||||
|
|
||||||
#endif /* _ASM_TIMEX_H */
|
#endif /* _ASM_TIMEX_H */
|
||||||
|
|
|
@ -70,6 +70,16 @@ static void event_handler(struct clock_event_device *dev)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void setup_jiffies_interrupt(int irq,
|
||||||
|
struct irqaction *action)
|
||||||
|
{
|
||||||
|
u16 tmp;
|
||||||
|
setup_irq(irq, action);
|
||||||
|
set_intr_level(irq, NUM2GxICR_LEVEL(CONFIG_TIMER_IRQ_LEVEL));
|
||||||
|
GxICR(irq) |= GxICR_ENABLE | GxICR_DETECT | GxICR_REQUEST;
|
||||||
|
tmp = GxICR(irq);
|
||||||
|
}
|
||||||
|
|
||||||
int __init init_clockevents(void)
|
int __init init_clockevents(void)
|
||||||
{
|
{
|
||||||
struct clock_event_device *cd;
|
struct clock_event_device *cd;
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
* 2 of the Licence, or (at your option) any later version.
|
* 2 of the Licence, or (at your option) any later version.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <linux/irqreturn.h>
|
||||||
|
|
||||||
struct clocksource;
|
struct clocksource;
|
||||||
struct clock_event_device;
|
struct clock_event_device;
|
||||||
|
|
||||||
|
|
|
@ -170,9 +170,9 @@ mn10300_cpupic_setaffinity(struct irq_data *d, const struct cpumask *mask,
|
||||||
case SC1TXIRQ:
|
case SC1TXIRQ:
|
||||||
#ifdef CONFIG_MN10300_TTYSM1_TIMER12
|
#ifdef CONFIG_MN10300_TTYSM1_TIMER12
|
||||||
case TM12IRQ:
|
case TM12IRQ:
|
||||||
#elif CONFIG_MN10300_TTYSM1_TIMER9
|
#elif defined(CONFIG_MN10300_TTYSM1_TIMER9)
|
||||||
case TM9IRQ:
|
case TM9IRQ:
|
||||||
#elif CONFIG_MN10300_TTYSM1_TIMER3
|
#elif defined(CONFIG_MN10300_TTYSM1_TIMER3)
|
||||||
case TM3IRQ:
|
case TM3IRQ:
|
||||||
#endif /* CONFIG_MN10300_TTYSM1_TIMER12 */
|
#endif /* CONFIG_MN10300_TTYSM1_TIMER12 */
|
||||||
#endif /* CONFIG_MN10300_TTYSM1 */
|
#endif /* CONFIG_MN10300_TTYSM1 */
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include <linux/kdebug.h>
|
#include <linux/kdebug.h>
|
||||||
#include <linux/bug.h>
|
#include <linux/bug.h>
|
||||||
#include <linux/irq.h>
|
#include <linux/irq.h>
|
||||||
|
#include <linux/export.h>
|
||||||
#include <asm/processor.h>
|
#include <asm/processor.h>
|
||||||
#include <linux/uaccess.h>
|
#include <linux/uaccess.h>
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include <linux/string.h>
|
#include <linux/string.h>
|
||||||
#include <linux/pci.h>
|
#include <linux/pci.h>
|
||||||
#include <linux/gfp.h>
|
#include <linux/gfp.h>
|
||||||
|
#include <linux/export.h>
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
|
|
||||||
static unsigned long pci_sram_allocated = 0xbc000000;
|
static unsigned long pci_sram_allocated = 0xbc000000;
|
||||||
|
|
|
@ -11,10 +11,6 @@
|
||||||
#ifndef _ASM_UNIT_TIMEX_H
|
#ifndef _ASM_UNIT_TIMEX_H
|
||||||
#define _ASM_UNIT_TIMEX_H
|
#define _ASM_UNIT_TIMEX_H
|
||||||
|
|
||||||
#ifndef __ASSEMBLY__
|
|
||||||
#include <linux/irq.h>
|
|
||||||
#endif /* __ASSEMBLY__ */
|
|
||||||
|
|
||||||
#include <asm/timer-regs.h>
|
#include <asm/timer-regs.h>
|
||||||
#include <unit/clock.h>
|
#include <unit/clock.h>
|
||||||
#include <asm/param.h>
|
#include <asm/param.h>
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
|
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
|
#include <asm/irq.h>
|
||||||
#include <asm/timex.h>
|
#include <asm/timex.h>
|
||||||
#include <asm/processor.h>
|
#include <asm/processor.h>
|
||||||
#include <asm/intctl-regs.h>
|
#include <asm/intctl-regs.h>
|
||||||
|
|
|
@ -11,10 +11,6 @@
|
||||||
#ifndef _ASM_UNIT_TIMEX_H
|
#ifndef _ASM_UNIT_TIMEX_H
|
||||||
#define _ASM_UNIT_TIMEX_H
|
#define _ASM_UNIT_TIMEX_H
|
||||||
|
|
||||||
#ifndef __ASSEMBLY__
|
|
||||||
#include <linux/irq.h>
|
|
||||||
#endif /* __ASSEMBLY__ */
|
|
||||||
|
|
||||||
#include <asm/timer-regs.h>
|
#include <asm/timer-regs.h>
|
||||||
#include <unit/clock.h>
|
#include <unit/clock.h>
|
||||||
#include <asm/param.h>
|
#include <asm/param.h>
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/pci.h>
|
#include <linux/pci.h>
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
|
#include <asm/irq.h>
|
||||||
#include <asm/setup.h>
|
#include <asm/setup.h>
|
||||||
#include <asm/processor.h>
|
#include <asm/processor.h>
|
||||||
#include <asm/intctl-regs.h>
|
#include <asm/intctl-regs.h>
|
||||||
|
|
|
@ -11,10 +11,6 @@
|
||||||
#ifndef _ASM_UNIT_TIMEX_H
|
#ifndef _ASM_UNIT_TIMEX_H
|
||||||
#define _ASM_UNIT_TIMEX_H
|
#define _ASM_UNIT_TIMEX_H
|
||||||
|
|
||||||
#ifndef __ASSEMBLY__
|
|
||||||
#include <linux/irq.h>
|
|
||||||
#endif /* __ASSEMBLY__ */
|
|
||||||
|
|
||||||
#include <asm/timer-regs.h>
|
#include <asm/timer-regs.h>
|
||||||
#include <unit/clock.h>
|
#include <unit/clock.h>
|
||||||
#include <asm/param.h>
|
#include <asm/param.h>
|
||||||
|
|
|
@ -277,7 +277,7 @@ void xtensa_elf_core_copy_regs (xtensa_gregset_t *elfregs, struct pt_regs *regs)
|
||||||
|
|
||||||
/* Don't leak any random bits. */
|
/* Don't leak any random bits. */
|
||||||
|
|
||||||
memset(elfregs, 0, sizeof (elfregs));
|
memset(elfregs, 0, sizeof(*elfregs));
|
||||||
|
|
||||||
/* Note: PS.EXCM is not set while user task is running; its
|
/* Note: PS.EXCM is not set while user task is running; its
|
||||||
* being set in regs->ps is for exception handling convenience.
|
* being set in regs->ps is for exception handling convenience.
|
||||||
|
|
|
@ -452,9 +452,9 @@ xpc_handle_activate_mq_msg_uv(struct xpc_partition *part,
|
||||||
|
|
||||||
if (msg->activate_gru_mq_desc_gpa !=
|
if (msg->activate_gru_mq_desc_gpa !=
|
||||||
part_uv->activate_gru_mq_desc_gpa) {
|
part_uv->activate_gru_mq_desc_gpa) {
|
||||||
spin_lock_irqsave(&part_uv->flags_lock, irq_flags);
|
spin_lock(&part_uv->flags_lock);
|
||||||
part_uv->flags &= ~XPC_P_CACHED_ACTIVATE_GRU_MQ_DESC_UV;
|
part_uv->flags &= ~XPC_P_CACHED_ACTIVATE_GRU_MQ_DESC_UV;
|
||||||
spin_unlock_irqrestore(&part_uv->flags_lock, irq_flags);
|
spin_unlock(&part_uv->flags_lock);
|
||||||
part_uv->activate_gru_mq_desc_gpa =
|
part_uv->activate_gru_mq_desc_gpa =
|
||||||
msg->activate_gru_mq_desc_gpa;
|
msg->activate_gru_mq_desc_gpa;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include <linux/mfd/abx500.h>
|
#include <linux/mfd/abx500.h>
|
||||||
#include <linux/mfd/abx500/ab8500.h>
|
#include <linux/mfd/abx500/ab8500.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
|
#include <linux/of.h>
|
||||||
|
|
||||||
#define AB8500_RTC_SOFF_STAT_REG 0x00
|
#define AB8500_RTC_SOFF_STAT_REG 0x00
|
||||||
#define AB8500_RTC_CC_CONF_REG 0x01
|
#define AB8500_RTC_CC_CONF_REG 0x01
|
||||||
|
@ -422,7 +423,7 @@ static int __devinit ab8500_rtc_probe(struct platform_device *pdev)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = request_threaded_irq(irq, NULL, rtc_alarm_handler,
|
err = request_threaded_irq(irq, NULL, rtc_alarm_handler,
|
||||||
IRQF_NO_SUSPEND, "ab8500-rtc", rtc);
|
IRQF_NO_SUSPEND | IRQF_ONESHOT, "ab8500-rtc", rtc);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
rtc_device_unregister(rtc);
|
rtc_device_unregister(rtc);
|
||||||
return err;
|
return err;
|
||||||
|
@ -430,7 +431,6 @@ static int __devinit ab8500_rtc_probe(struct platform_device *pdev)
|
||||||
|
|
||||||
platform_set_drvdata(pdev, rtc);
|
platform_set_drvdata(pdev, rtc);
|
||||||
|
|
||||||
|
|
||||||
err = ab8500_sysfs_rtc_register(&pdev->dev);
|
err = ab8500_sysfs_rtc_register(&pdev->dev);
|
||||||
if (err) {
|
if (err) {
|
||||||
dev_err(&pdev->dev, "sysfs RTC failed to register\n");
|
dev_err(&pdev->dev, "sysfs RTC failed to register\n");
|
||||||
|
@ -454,10 +454,16 @@ static int __devexit ab8500_rtc_remove(struct platform_device *pdev)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct of_device_id ab8500_rtc_match[] = {
|
||||||
|
{ .compatible = "stericsson,ab8500-rtc", },
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
static struct platform_driver ab8500_rtc_driver = {
|
static struct platform_driver ab8500_rtc_driver = {
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "ab8500-rtc",
|
.name = "ab8500-rtc",
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
|
.of_match_table = ab8500_rtc_match,
|
||||||
},
|
},
|
||||||
.probe = ab8500_rtc_probe,
|
.probe = ab8500_rtc_probe,
|
||||||
.remove = __devexit_p(ab8500_rtc_remove),
|
.remove = __devexit_p(ab8500_rtc_remove),
|
||||||
|
|
|
@ -202,10 +202,11 @@ static irqreturn_t mxc_rtc_interrupt(int irq, void *dev_id)
|
||||||
struct platform_device *pdev = dev_id;
|
struct platform_device *pdev = dev_id;
|
||||||
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
|
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
|
||||||
void __iomem *ioaddr = pdata->ioaddr;
|
void __iomem *ioaddr = pdata->ioaddr;
|
||||||
|
unsigned long flags;
|
||||||
u32 status;
|
u32 status;
|
||||||
u32 events = 0;
|
u32 events = 0;
|
||||||
|
|
||||||
spin_lock_irq(&pdata->rtc->irq_lock);
|
spin_lock_irqsave(&pdata->rtc->irq_lock, flags);
|
||||||
status = readw(ioaddr + RTC_RTCISR) & readw(ioaddr + RTC_RTCIENR);
|
status = readw(ioaddr + RTC_RTCISR) & readw(ioaddr + RTC_RTCIENR);
|
||||||
/* clear interrupt sources */
|
/* clear interrupt sources */
|
||||||
writew(status, ioaddr + RTC_RTCISR);
|
writew(status, ioaddr + RTC_RTCISR);
|
||||||
|
@ -224,7 +225,7 @@ static irqreturn_t mxc_rtc_interrupt(int irq, void *dev_id)
|
||||||
events |= (RTC_PF | RTC_IRQF);
|
events |= (RTC_PF | RTC_IRQF);
|
||||||
|
|
||||||
rtc_update_irq(pdata->rtc, 1, events);
|
rtc_update_irq(pdata->rtc, 1, events);
|
||||||
spin_unlock_irq(&pdata->rtc->irq_lock);
|
spin_unlock_irqrestore(&pdata->rtc->irq_lock, flags);
|
||||||
|
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
|
@ -458,12 +458,12 @@ static int __devexit spear_rtc_remove(struct platform_device *pdev)
|
||||||
clk_disable(config->clk);
|
clk_disable(config->clk);
|
||||||
clk_put(config->clk);
|
clk_put(config->clk);
|
||||||
iounmap(config->ioaddr);
|
iounmap(config->ioaddr);
|
||||||
kfree(config);
|
|
||||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||||
if (res)
|
if (res)
|
||||||
release_mem_region(res->start, resource_size(res));
|
release_mem_region(res->start, resource_size(res));
|
||||||
platform_set_drvdata(pdev, NULL);
|
platform_set_drvdata(pdev, NULL);
|
||||||
rtc_device_unregister(config->rtc);
|
rtc_device_unregister(config->rtc);
|
||||||
|
kfree(config);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -510,7 +510,7 @@ static int __devinit twl_rtc_probe(struct platform_device *pdev)
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = request_threaded_irq(irq, NULL, twl_rtc_interrupt,
|
ret = request_threaded_irq(irq, NULL, twl_rtc_interrupt,
|
||||||
IRQF_TRIGGER_RISING,
|
IRQF_TRIGGER_RISING | IRQF_ONESHOT,
|
||||||
dev_name(&rtc->dev), rtc);
|
dev_name(&rtc->dev), rtc);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
dev_err(&pdev->dev, "IRQ is not free.\n");
|
dev_err(&pdev->dev, "IRQ is not free.\n");
|
||||||
|
|
|
@ -738,22 +738,21 @@ static int
|
||||||
fat_encode_fh(struct inode *inode, __u32 *fh, int *lenp, struct inode *parent)
|
fat_encode_fh(struct inode *inode, __u32 *fh, int *lenp, struct inode *parent)
|
||||||
{
|
{
|
||||||
int len = *lenp;
|
int len = *lenp;
|
||||||
u32 ipos_h, ipos_m, ipos_l;
|
struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
|
||||||
|
loff_t i_pos;
|
||||||
|
|
||||||
if (len < 5) {
|
if (len < 5) {
|
||||||
*lenp = 5;
|
*lenp = 5;
|
||||||
return 255; /* no room */
|
return 255; /* no room */
|
||||||
}
|
}
|
||||||
|
|
||||||
ipos_h = MSDOS_I(inode)->i_pos >> 8;
|
i_pos = fat_i_pos_read(sbi, inode);
|
||||||
ipos_m = (MSDOS_I(inode)->i_pos & 0xf0) << 24;
|
|
||||||
ipos_l = (MSDOS_I(inode)->i_pos & 0x0f) << 28;
|
|
||||||
*lenp = 5;
|
*lenp = 5;
|
||||||
fh[0] = inode->i_ino;
|
fh[0] = inode->i_ino;
|
||||||
fh[1] = inode->i_generation;
|
fh[1] = inode->i_generation;
|
||||||
fh[2] = ipos_h;
|
fh[2] = i_pos >> 8;
|
||||||
fh[3] = ipos_m | MSDOS_I(inode)->i_logstart;
|
fh[3] = ((i_pos & 0xf0) << 24) | MSDOS_I(inode)->i_logstart;
|
||||||
fh[4] = ipos_l;
|
fh[4] = (i_pos & 0x0f) << 28;
|
||||||
if (parent)
|
if (parent)
|
||||||
fh[4] |= MSDOS_I(parent)->i_logstart;
|
fh[4] |= MSDOS_I(parent)->i_logstart;
|
||||||
return 3;
|
return 3;
|
||||||
|
|
|
@ -1950,7 +1950,7 @@ static int __ocfs2_change_file_space(struct file *file, struct inode *inode,
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
mlog_errno(ret);
|
mlog_errno(ret);
|
||||||
|
|
||||||
if (file->f_flags & O_SYNC)
|
if (file && (file->f_flags & O_SYNC))
|
||||||
handle->h_sync = 1;
|
handle->h_sync = 1;
|
||||||
|
|
||||||
ocfs2_commit_trans(osb, handle);
|
ocfs2_commit_trans(osb, handle);
|
||||||
|
|
|
@ -110,6 +110,7 @@ int ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize)
|
||||||
|
|
||||||
/* prevent the page from being discarded on memory pressure */
|
/* prevent the page from being discarded on memory pressure */
|
||||||
SetPageDirty(page);
|
SetPageDirty(page);
|
||||||
|
SetPageUptodate(page);
|
||||||
|
|
||||||
unlock_page(page);
|
unlock_page(page);
|
||||||
put_page(page);
|
put_page(page);
|
||||||
|
|
|
@ -91,6 +91,11 @@ extern void *__alloc_bootmem_node_nopanic(pg_data_t *pgdat,
|
||||||
unsigned long size,
|
unsigned long size,
|
||||||
unsigned long align,
|
unsigned long align,
|
||||||
unsigned long goal);
|
unsigned long goal);
|
||||||
|
void *___alloc_bootmem_node_nopanic(pg_data_t *pgdat,
|
||||||
|
unsigned long size,
|
||||||
|
unsigned long align,
|
||||||
|
unsigned long goal,
|
||||||
|
unsigned long limit);
|
||||||
extern void *__alloc_bootmem_low(unsigned long size,
|
extern void *__alloc_bootmem_low(unsigned long size,
|
||||||
unsigned long align,
|
unsigned long align,
|
||||||
unsigned long goal);
|
unsigned long goal);
|
||||||
|
|
|
@ -50,9 +50,7 @@ phys_addr_t memblock_find_in_range_node(phys_addr_t start, phys_addr_t end,
|
||||||
phys_addr_t size, phys_addr_t align, int nid);
|
phys_addr_t size, phys_addr_t align, int nid);
|
||||||
phys_addr_t memblock_find_in_range(phys_addr_t start, phys_addr_t end,
|
phys_addr_t memblock_find_in_range(phys_addr_t start, phys_addr_t end,
|
||||||
phys_addr_t size, phys_addr_t align);
|
phys_addr_t size, phys_addr_t align);
|
||||||
int memblock_free_reserved_regions(void);
|
phys_addr_t get_allocated_memblock_reserved_regions_info(phys_addr_t *addr);
|
||||||
int memblock_reserve_reserved_regions(void);
|
|
||||||
|
|
||||||
void memblock_allow_resize(void);
|
void memblock_allow_resize(void);
|
||||||
int memblock_add_node(phys_addr_t base, phys_addr_t size, int nid);
|
int memblock_add_node(phys_addr_t base, phys_addr_t size, int nid);
|
||||||
int memblock_add(phys_addr_t base, phys_addr_t size);
|
int memblock_add(phys_addr_t base, phys_addr_t size);
|
||||||
|
|
|
@ -694,7 +694,7 @@ typedef struct pglist_data {
|
||||||
range, including holes */
|
range, including holes */
|
||||||
int node_id;
|
int node_id;
|
||||||
wait_queue_head_t kswapd_wait;
|
wait_queue_head_t kswapd_wait;
|
||||||
struct task_struct *kswapd;
|
struct task_struct *kswapd; /* Protected by lock_memory_hotplug() */
|
||||||
int kswapd_max_order;
|
int kswapd_max_order;
|
||||||
enum zone_type classzone_idx;
|
enum zone_type classzone_idx;
|
||||||
} pg_data_t;
|
} pg_data_t;
|
||||||
|
|
16
kernel/sys.c
16
kernel/sys.c
|
@ -1788,7 +1788,6 @@ SYSCALL_DEFINE1(umask, int, mask)
|
||||||
#ifdef CONFIG_CHECKPOINT_RESTORE
|
#ifdef CONFIG_CHECKPOINT_RESTORE
|
||||||
static int prctl_set_mm_exe_file(struct mm_struct *mm, unsigned int fd)
|
static int prctl_set_mm_exe_file(struct mm_struct *mm, unsigned int fd)
|
||||||
{
|
{
|
||||||
struct vm_area_struct *vma;
|
|
||||||
struct file *exe_file;
|
struct file *exe_file;
|
||||||
struct dentry *dentry;
|
struct dentry *dentry;
|
||||||
int err;
|
int err;
|
||||||
|
@ -1816,13 +1815,17 @@ static int prctl_set_mm_exe_file(struct mm_struct *mm, unsigned int fd)
|
||||||
down_write(&mm->mmap_sem);
|
down_write(&mm->mmap_sem);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Forbid mm->exe_file change if there are mapped other files.
|
* Forbid mm->exe_file change if old file still mapped.
|
||||||
*/
|
*/
|
||||||
err = -EBUSY;
|
err = -EBUSY;
|
||||||
for (vma = mm->mmap; vma; vma = vma->vm_next) {
|
if (mm->exe_file) {
|
||||||
if (vma->vm_file && !path_equal(&vma->vm_file->f_path,
|
struct vm_area_struct *vma;
|
||||||
&exe_file->f_path))
|
|
||||||
goto exit_unlock;
|
for (vma = mm->mmap; vma; vma = vma->vm_next)
|
||||||
|
if (vma->vm_file &&
|
||||||
|
path_equal(&vma->vm_file->f_path,
|
||||||
|
&mm->exe_file->f_path))
|
||||||
|
goto exit_unlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1835,6 +1838,7 @@ static int prctl_set_mm_exe_file(struct mm_struct *mm, unsigned int fd)
|
||||||
if (test_and_set_bit(MMF_EXE_FILE_CHANGED, &mm->flags))
|
if (test_and_set_bit(MMF_EXE_FILE_CHANGED, &mm->flags))
|
||||||
goto exit_unlock;
|
goto exit_unlock;
|
||||||
|
|
||||||
|
err = 0;
|
||||||
set_mm_exe_file(mm, exe_file);
|
set_mm_exe_file(mm, exe_file);
|
||||||
exit_unlock:
|
exit_unlock:
|
||||||
up_write(&mm->mmap_sem);
|
up_write(&mm->mmap_sem);
|
||||||
|
|
|
@ -698,7 +698,7 @@ void * __init __alloc_bootmem(unsigned long size, unsigned long align,
|
||||||
return ___alloc_bootmem(size, align, goal, limit);
|
return ___alloc_bootmem(size, align, goal, limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void * __init ___alloc_bootmem_node_nopanic(pg_data_t *pgdat,
|
void * __init ___alloc_bootmem_node_nopanic(pg_data_t *pgdat,
|
||||||
unsigned long size, unsigned long align,
|
unsigned long size, unsigned long align,
|
||||||
unsigned long goal, unsigned long limit)
|
unsigned long goal, unsigned long limit)
|
||||||
{
|
{
|
||||||
|
|
|
@ -701,8 +701,11 @@ static int compact_zone(struct zone *zone, struct compact_control *cc)
|
||||||
if (err) {
|
if (err) {
|
||||||
putback_lru_pages(&cc->migratepages);
|
putback_lru_pages(&cc->migratepages);
|
||||||
cc->nr_migratepages = 0;
|
cc->nr_migratepages = 0;
|
||||||
|
if (err == -ENOMEM) {
|
||||||
|
ret = COMPACT_PARTIAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
|
|
@ -143,30 +143,6 @@ phys_addr_t __init_memblock memblock_find_in_range(phys_addr_t start,
|
||||||
MAX_NUMNODES);
|
MAX_NUMNODES);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Free memblock.reserved.regions
|
|
||||||
*/
|
|
||||||
int __init_memblock memblock_free_reserved_regions(void)
|
|
||||||
{
|
|
||||||
if (memblock.reserved.regions == memblock_reserved_init_regions)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return memblock_free(__pa(memblock.reserved.regions),
|
|
||||||
sizeof(struct memblock_region) * memblock.reserved.max);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Reserve memblock.reserved.regions
|
|
||||||
*/
|
|
||||||
int __init_memblock memblock_reserve_reserved_regions(void)
|
|
||||||
{
|
|
||||||
if (memblock.reserved.regions == memblock_reserved_init_regions)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return memblock_reserve(__pa(memblock.reserved.regions),
|
|
||||||
sizeof(struct memblock_region) * memblock.reserved.max);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __init_memblock memblock_remove_region(struct memblock_type *type, unsigned long r)
|
static void __init_memblock memblock_remove_region(struct memblock_type *type, unsigned long r)
|
||||||
{
|
{
|
||||||
type->total_size -= type->regions[r].size;
|
type->total_size -= type->regions[r].size;
|
||||||
|
@ -184,6 +160,18 @@ static void __init_memblock memblock_remove_region(struct memblock_type *type, u
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
phys_addr_t __init_memblock get_allocated_memblock_reserved_regions_info(
|
||||||
|
phys_addr_t *addr)
|
||||||
|
{
|
||||||
|
if (memblock.reserved.regions == memblock_reserved_init_regions)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
*addr = __pa(memblock.reserved.regions);
|
||||||
|
|
||||||
|
return PAGE_ALIGN(sizeof(struct memblock_region) *
|
||||||
|
memblock.reserved.max);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* memblock_double_array - double the size of the memblock regions array
|
* memblock_double_array - double the size of the memblock regions array
|
||||||
* @type: memblock type of the regions array being doubled
|
* @type: memblock type of the regions array being doubled
|
||||||
|
@ -204,6 +192,7 @@ static int __init_memblock memblock_double_array(struct memblock_type *type,
|
||||||
phys_addr_t new_area_size)
|
phys_addr_t new_area_size)
|
||||||
{
|
{
|
||||||
struct memblock_region *new_array, *old_array;
|
struct memblock_region *new_array, *old_array;
|
||||||
|
phys_addr_t old_alloc_size, new_alloc_size;
|
||||||
phys_addr_t old_size, new_size, addr;
|
phys_addr_t old_size, new_size, addr;
|
||||||
int use_slab = slab_is_available();
|
int use_slab = slab_is_available();
|
||||||
int *in_slab;
|
int *in_slab;
|
||||||
|
@ -217,6 +206,12 @@ static int __init_memblock memblock_double_array(struct memblock_type *type,
|
||||||
/* Calculate new doubled size */
|
/* Calculate new doubled size */
|
||||||
old_size = type->max * sizeof(struct memblock_region);
|
old_size = type->max * sizeof(struct memblock_region);
|
||||||
new_size = old_size << 1;
|
new_size = old_size << 1;
|
||||||
|
/*
|
||||||
|
* We need to allocated new one align to PAGE_SIZE,
|
||||||
|
* so we can free them completely later.
|
||||||
|
*/
|
||||||
|
old_alloc_size = PAGE_ALIGN(old_size);
|
||||||
|
new_alloc_size = PAGE_ALIGN(new_size);
|
||||||
|
|
||||||
/* Retrieve the slab flag */
|
/* Retrieve the slab flag */
|
||||||
if (type == &memblock.memory)
|
if (type == &memblock.memory)
|
||||||
|
@ -245,11 +240,11 @@ static int __init_memblock memblock_double_array(struct memblock_type *type,
|
||||||
|
|
||||||
addr = memblock_find_in_range(new_area_start + new_area_size,
|
addr = memblock_find_in_range(new_area_start + new_area_size,
|
||||||
memblock.current_limit,
|
memblock.current_limit,
|
||||||
new_size, sizeof(phys_addr_t));
|
new_alloc_size, PAGE_SIZE);
|
||||||
if (!addr && new_area_size)
|
if (!addr && new_area_size)
|
||||||
addr = memblock_find_in_range(0,
|
addr = memblock_find_in_range(0,
|
||||||
min(new_area_start, memblock.current_limit),
|
min(new_area_start, memblock.current_limit),
|
||||||
new_size, sizeof(phys_addr_t));
|
new_alloc_size, PAGE_SIZE);
|
||||||
|
|
||||||
new_array = addr ? __va(addr) : 0;
|
new_array = addr ? __va(addr) : 0;
|
||||||
}
|
}
|
||||||
|
@ -279,13 +274,13 @@ static int __init_memblock memblock_double_array(struct memblock_type *type,
|
||||||
kfree(old_array);
|
kfree(old_array);
|
||||||
else if (old_array != memblock_memory_init_regions &&
|
else if (old_array != memblock_memory_init_regions &&
|
||||||
old_array != memblock_reserved_init_regions)
|
old_array != memblock_reserved_init_regions)
|
||||||
memblock_free(__pa(old_array), old_size);
|
memblock_free(__pa(old_array), old_alloc_size);
|
||||||
|
|
||||||
/* Reserve the new array if that comes from the memblock.
|
/* Reserve the new array if that comes from the memblock.
|
||||||
* Otherwise, we needn't do it
|
* Otherwise, we needn't do it
|
||||||
*/
|
*/
|
||||||
if (!use_slab)
|
if (!use_slab)
|
||||||
BUG_ON(memblock_reserve(addr, new_size));
|
BUG_ON(memblock_reserve(addr, new_alloc_size));
|
||||||
|
|
||||||
/* Update slab flag */
|
/* Update slab flag */
|
||||||
*in_slab = use_slab;
|
*in_slab = use_slab;
|
||||||
|
|
|
@ -618,7 +618,7 @@ int __ref add_memory(int nid, u64 start, u64 size)
|
||||||
pgdat = hotadd_new_pgdat(nid, start);
|
pgdat = hotadd_new_pgdat(nid, start);
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
if (!pgdat)
|
if (!pgdat)
|
||||||
goto out;
|
goto error;
|
||||||
new_pgdat = 1;
|
new_pgdat = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -105,27 +105,35 @@ static void __init __free_pages_memory(unsigned long start, unsigned long end)
|
||||||
__free_pages_bootmem(pfn_to_page(i), 0);
|
__free_pages_bootmem(pfn_to_page(i), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned long __init __free_memory_core(phys_addr_t start,
|
||||||
|
phys_addr_t end)
|
||||||
|
{
|
||||||
|
unsigned long start_pfn = PFN_UP(start);
|
||||||
|
unsigned long end_pfn = min_t(unsigned long,
|
||||||
|
PFN_DOWN(end), max_low_pfn);
|
||||||
|
|
||||||
|
if (start_pfn > end_pfn)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
__free_pages_memory(start_pfn, end_pfn);
|
||||||
|
|
||||||
|
return end_pfn - start_pfn;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned long __init free_low_memory_core_early(int nodeid)
|
unsigned long __init free_low_memory_core_early(int nodeid)
|
||||||
{
|
{
|
||||||
unsigned long count = 0;
|
unsigned long count = 0;
|
||||||
phys_addr_t start, end;
|
phys_addr_t start, end, size;
|
||||||
u64 i;
|
u64 i;
|
||||||
|
|
||||||
/* free reserved array temporarily so that it's treated as free area */
|
for_each_free_mem_range(i, MAX_NUMNODES, &start, &end, NULL)
|
||||||
memblock_free_reserved_regions();
|
count += __free_memory_core(start, end);
|
||||||
|
|
||||||
for_each_free_mem_range(i, MAX_NUMNODES, &start, &end, NULL) {
|
/* free range that is used for reserved array if we allocate it */
|
||||||
unsigned long start_pfn = PFN_UP(start);
|
size = get_allocated_memblock_reserved_regions_info(&start);
|
||||||
unsigned long end_pfn = min_t(unsigned long,
|
if (size)
|
||||||
PFN_DOWN(end), max_low_pfn);
|
count += __free_memory_core(start, start + size);
|
||||||
if (start_pfn < end_pfn) {
|
|
||||||
__free_pages_memory(start_pfn, end_pfn);
|
|
||||||
count += end_pfn - start_pfn;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* put region array back? */
|
|
||||||
memblock_reserve_reserved_regions();
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -274,7 +282,7 @@ void * __init __alloc_bootmem(unsigned long size, unsigned long align,
|
||||||
return ___alloc_bootmem(size, align, goal, limit);
|
return ___alloc_bootmem(size, align, goal, limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void * __init ___alloc_bootmem_node_nopanic(pg_data_t *pgdat,
|
void * __init ___alloc_bootmem_node_nopanic(pg_data_t *pgdat,
|
||||||
unsigned long size,
|
unsigned long size,
|
||||||
unsigned long align,
|
unsigned long align,
|
||||||
unsigned long goal,
|
unsigned long goal,
|
||||||
|
|
195
mm/shmem.c
195
mm/shmem.c
|
@ -263,6 +263,24 @@ static int shmem_radix_tree_replace(struct address_space *mapping,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sometimes, before we decide whether to proceed or to fail, we must check
|
||||||
|
* that an entry was not already brought back from swap by a racing thread.
|
||||||
|
*
|
||||||
|
* Checking page is not enough: by the time a SwapCache page is locked, it
|
||||||
|
* might be reused, and again be SwapCache, using the same swap as before.
|
||||||
|
*/
|
||||||
|
static bool shmem_confirm_swap(struct address_space *mapping,
|
||||||
|
pgoff_t index, swp_entry_t swap)
|
||||||
|
{
|
||||||
|
void *item;
|
||||||
|
|
||||||
|
rcu_read_lock();
|
||||||
|
item = radix_tree_lookup(&mapping->page_tree, index);
|
||||||
|
rcu_read_unlock();
|
||||||
|
return item == swp_to_radix_entry(swap);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Like add_to_page_cache_locked, but error if expected item has gone.
|
* Like add_to_page_cache_locked, but error if expected item has gone.
|
||||||
*/
|
*/
|
||||||
|
@ -270,40 +288,31 @@ static int shmem_add_to_page_cache(struct page *page,
|
||||||
struct address_space *mapping,
|
struct address_space *mapping,
|
||||||
pgoff_t index, gfp_t gfp, void *expected)
|
pgoff_t index, gfp_t gfp, void *expected)
|
||||||
{
|
{
|
||||||
int error = 0;
|
int error;
|
||||||
|
|
||||||
VM_BUG_ON(!PageLocked(page));
|
VM_BUG_ON(!PageLocked(page));
|
||||||
VM_BUG_ON(!PageSwapBacked(page));
|
VM_BUG_ON(!PageSwapBacked(page));
|
||||||
|
|
||||||
if (!expected)
|
page_cache_get(page);
|
||||||
error = radix_tree_preload(gfp & GFP_RECLAIM_MASK);
|
page->mapping = mapping;
|
||||||
if (!error) {
|
page->index = index;
|
||||||
page_cache_get(page);
|
|
||||||
page->mapping = mapping;
|
|
||||||
page->index = index;
|
|
||||||
|
|
||||||
spin_lock_irq(&mapping->tree_lock);
|
spin_lock_irq(&mapping->tree_lock);
|
||||||
if (!expected)
|
if (!expected)
|
||||||
error = radix_tree_insert(&mapping->page_tree,
|
error = radix_tree_insert(&mapping->page_tree, index, page);
|
||||||
index, page);
|
else
|
||||||
else
|
error = shmem_radix_tree_replace(mapping, index, expected,
|
||||||
error = shmem_radix_tree_replace(mapping, index,
|
page);
|
||||||
expected, page);
|
if (!error) {
|
||||||
if (!error) {
|
mapping->nrpages++;
|
||||||
mapping->nrpages++;
|
__inc_zone_page_state(page, NR_FILE_PAGES);
|
||||||
__inc_zone_page_state(page, NR_FILE_PAGES);
|
__inc_zone_page_state(page, NR_SHMEM);
|
||||||
__inc_zone_page_state(page, NR_SHMEM);
|
spin_unlock_irq(&mapping->tree_lock);
|
||||||
spin_unlock_irq(&mapping->tree_lock);
|
} else {
|
||||||
} else {
|
page->mapping = NULL;
|
||||||
page->mapping = NULL;
|
spin_unlock_irq(&mapping->tree_lock);
|
||||||
spin_unlock_irq(&mapping->tree_lock);
|
page_cache_release(page);
|
||||||
page_cache_release(page);
|
|
||||||
}
|
|
||||||
if (!expected)
|
|
||||||
radix_tree_preload_end();
|
|
||||||
}
|
}
|
||||||
if (error)
|
|
||||||
mem_cgroup_uncharge_cache_page(page);
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1124,9 +1133,9 @@ repeat:
|
||||||
/* We have to do this with page locked to prevent races */
|
/* We have to do this with page locked to prevent races */
|
||||||
lock_page(page);
|
lock_page(page);
|
||||||
if (!PageSwapCache(page) || page_private(page) != swap.val ||
|
if (!PageSwapCache(page) || page_private(page) != swap.val ||
|
||||||
page->mapping) {
|
!shmem_confirm_swap(mapping, index, swap)) {
|
||||||
error = -EEXIST; /* try again */
|
error = -EEXIST; /* try again */
|
||||||
goto failed;
|
goto unlock;
|
||||||
}
|
}
|
||||||
if (!PageUptodate(page)) {
|
if (!PageUptodate(page)) {
|
||||||
error = -EIO;
|
error = -EIO;
|
||||||
|
@ -1142,9 +1151,12 @@ repeat:
|
||||||
|
|
||||||
error = mem_cgroup_cache_charge(page, current->mm,
|
error = mem_cgroup_cache_charge(page, current->mm,
|
||||||
gfp & GFP_RECLAIM_MASK);
|
gfp & GFP_RECLAIM_MASK);
|
||||||
if (!error)
|
if (!error) {
|
||||||
error = shmem_add_to_page_cache(page, mapping, index,
|
error = shmem_add_to_page_cache(page, mapping, index,
|
||||||
gfp, swp_to_radix_entry(swap));
|
gfp, swp_to_radix_entry(swap));
|
||||||
|
/* We already confirmed swap, and make no allocation */
|
||||||
|
VM_BUG_ON(error);
|
||||||
|
}
|
||||||
if (error)
|
if (error)
|
||||||
goto failed;
|
goto failed;
|
||||||
|
|
||||||
|
@ -1181,11 +1193,18 @@ repeat:
|
||||||
__set_page_locked(page);
|
__set_page_locked(page);
|
||||||
error = mem_cgroup_cache_charge(page, current->mm,
|
error = mem_cgroup_cache_charge(page, current->mm,
|
||||||
gfp & GFP_RECLAIM_MASK);
|
gfp & GFP_RECLAIM_MASK);
|
||||||
if (!error)
|
|
||||||
error = shmem_add_to_page_cache(page, mapping, index,
|
|
||||||
gfp, NULL);
|
|
||||||
if (error)
|
if (error)
|
||||||
goto decused;
|
goto decused;
|
||||||
|
error = radix_tree_preload(gfp & GFP_RECLAIM_MASK);
|
||||||
|
if (!error) {
|
||||||
|
error = shmem_add_to_page_cache(page, mapping, index,
|
||||||
|
gfp, NULL);
|
||||||
|
radix_tree_preload_end();
|
||||||
|
}
|
||||||
|
if (error) {
|
||||||
|
mem_cgroup_uncharge_cache_page(page);
|
||||||
|
goto decused;
|
||||||
|
}
|
||||||
lru_cache_add_anon(page);
|
lru_cache_add_anon(page);
|
||||||
|
|
||||||
spin_lock(&info->lock);
|
spin_lock(&info->lock);
|
||||||
|
@ -1245,14 +1264,10 @@ decused:
|
||||||
unacct:
|
unacct:
|
||||||
shmem_unacct_blocks(info->flags, 1);
|
shmem_unacct_blocks(info->flags, 1);
|
||||||
failed:
|
failed:
|
||||||
if (swap.val && error != -EINVAL) {
|
if (swap.val && error != -EINVAL &&
|
||||||
struct page *test = find_get_page(mapping, index);
|
!shmem_confirm_swap(mapping, index, swap))
|
||||||
if (test && !radix_tree_exceptional_entry(test))
|
error = -EEXIST;
|
||||||
page_cache_release(test);
|
unlock:
|
||||||
/* Have another try if the entry has changed */
|
|
||||||
if (test != swp_to_radix_entry(swap))
|
|
||||||
error = -EEXIST;
|
|
||||||
}
|
|
||||||
if (page) {
|
if (page) {
|
||||||
unlock_page(page);
|
unlock_page(page);
|
||||||
page_cache_release(page);
|
page_cache_release(page);
|
||||||
|
@ -1264,7 +1279,7 @@ failed:
|
||||||
spin_unlock(&info->lock);
|
spin_unlock(&info->lock);
|
||||||
goto repeat;
|
goto repeat;
|
||||||
}
|
}
|
||||||
if (error == -EEXIST)
|
if (error == -EEXIST) /* from above or from radix_tree_insert */
|
||||||
goto repeat;
|
goto repeat;
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
@ -1692,98 +1707,6 @@ static ssize_t shmem_file_splice_read(struct file *in, loff_t *ppos,
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* llseek SEEK_DATA or SEEK_HOLE through the radix_tree.
|
|
||||||
*/
|
|
||||||
static pgoff_t shmem_seek_hole_data(struct address_space *mapping,
|
|
||||||
pgoff_t index, pgoff_t end, int origin)
|
|
||||||
{
|
|
||||||
struct page *page;
|
|
||||||
struct pagevec pvec;
|
|
||||||
pgoff_t indices[PAGEVEC_SIZE];
|
|
||||||
bool done = false;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
pagevec_init(&pvec, 0);
|
|
||||||
pvec.nr = 1; /* start small: we may be there already */
|
|
||||||
while (!done) {
|
|
||||||
pvec.nr = shmem_find_get_pages_and_swap(mapping, index,
|
|
||||||
pvec.nr, pvec.pages, indices);
|
|
||||||
if (!pvec.nr) {
|
|
||||||
if (origin == SEEK_DATA)
|
|
||||||
index = end;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
for (i = 0; i < pvec.nr; i++, index++) {
|
|
||||||
if (index < indices[i]) {
|
|
||||||
if (origin == SEEK_HOLE) {
|
|
||||||
done = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
index = indices[i];
|
|
||||||
}
|
|
||||||
page = pvec.pages[i];
|
|
||||||
if (page && !radix_tree_exceptional_entry(page)) {
|
|
||||||
if (!PageUptodate(page))
|
|
||||||
page = NULL;
|
|
||||||
}
|
|
||||||
if (index >= end ||
|
|
||||||
(page && origin == SEEK_DATA) ||
|
|
||||||
(!page && origin == SEEK_HOLE)) {
|
|
||||||
done = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
shmem_deswap_pagevec(&pvec);
|
|
||||||
pagevec_release(&pvec);
|
|
||||||
pvec.nr = PAGEVEC_SIZE;
|
|
||||||
cond_resched();
|
|
||||||
}
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
|
|
||||||
static loff_t shmem_file_llseek(struct file *file, loff_t offset, int origin)
|
|
||||||
{
|
|
||||||
struct address_space *mapping;
|
|
||||||
struct inode *inode;
|
|
||||||
pgoff_t start, end;
|
|
||||||
loff_t new_offset;
|
|
||||||
|
|
||||||
if (origin != SEEK_DATA && origin != SEEK_HOLE)
|
|
||||||
return generic_file_llseek_size(file, offset, origin,
|
|
||||||
MAX_LFS_FILESIZE);
|
|
||||||
mapping = file->f_mapping;
|
|
||||||
inode = mapping->host;
|
|
||||||
mutex_lock(&inode->i_mutex);
|
|
||||||
/* We're holding i_mutex so we can access i_size directly */
|
|
||||||
|
|
||||||
if (offset < 0)
|
|
||||||
offset = -EINVAL;
|
|
||||||
else if (offset >= inode->i_size)
|
|
||||||
offset = -ENXIO;
|
|
||||||
else {
|
|
||||||
start = offset >> PAGE_CACHE_SHIFT;
|
|
||||||
end = (inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
|
|
||||||
new_offset = shmem_seek_hole_data(mapping, start, end, origin);
|
|
||||||
new_offset <<= PAGE_CACHE_SHIFT;
|
|
||||||
if (new_offset > offset) {
|
|
||||||
if (new_offset < inode->i_size)
|
|
||||||
offset = new_offset;
|
|
||||||
else if (origin == SEEK_DATA)
|
|
||||||
offset = -ENXIO;
|
|
||||||
else
|
|
||||||
offset = inode->i_size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (offset >= 0 && offset != file->f_pos) {
|
|
||||||
file->f_pos = offset;
|
|
||||||
file->f_version = 0;
|
|
||||||
}
|
|
||||||
mutex_unlock(&inode->i_mutex);
|
|
||||||
return offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
static long shmem_fallocate(struct file *file, int mode, loff_t offset,
|
static long shmem_fallocate(struct file *file, int mode, loff_t offset,
|
||||||
loff_t len)
|
loff_t len)
|
||||||
{
|
{
|
||||||
|
@ -2787,7 +2710,7 @@ static const struct address_space_operations shmem_aops = {
|
||||||
static const struct file_operations shmem_file_operations = {
|
static const struct file_operations shmem_file_operations = {
|
||||||
.mmap = shmem_mmap,
|
.mmap = shmem_mmap,
|
||||||
#ifdef CONFIG_TMPFS
|
#ifdef CONFIG_TMPFS
|
||||||
.llseek = shmem_file_llseek,
|
.llseek = generic_file_llseek,
|
||||||
.read = do_sync_read,
|
.read = do_sync_read,
|
||||||
.write = do_sync_write,
|
.write = do_sync_write,
|
||||||
.aio_read = shmem_file_aio_read,
|
.aio_read = shmem_file_aio_read,
|
||||||
|
|
20
mm/sparse.c
20
mm/sparse.c
|
@ -275,8 +275,9 @@ static unsigned long * __init
|
||||||
sparse_early_usemaps_alloc_pgdat_section(struct pglist_data *pgdat,
|
sparse_early_usemaps_alloc_pgdat_section(struct pglist_data *pgdat,
|
||||||
unsigned long size)
|
unsigned long size)
|
||||||
{
|
{
|
||||||
pg_data_t *host_pgdat;
|
unsigned long goal, limit;
|
||||||
unsigned long goal;
|
unsigned long *p;
|
||||||
|
int nid;
|
||||||
/*
|
/*
|
||||||
* A page may contain usemaps for other sections preventing the
|
* A page may contain usemaps for other sections preventing the
|
||||||
* page being freed and making a section unremovable while
|
* page being freed and making a section unremovable while
|
||||||
|
@ -287,10 +288,17 @@ sparse_early_usemaps_alloc_pgdat_section(struct pglist_data *pgdat,
|
||||||
* from the same section as the pgdat where possible to avoid
|
* from the same section as the pgdat where possible to avoid
|
||||||
* this problem.
|
* this problem.
|
||||||
*/
|
*/
|
||||||
goal = __pa(pgdat) & PAGE_SECTION_MASK;
|
goal = __pa(pgdat) & (PAGE_SECTION_MASK << PAGE_SHIFT);
|
||||||
host_pgdat = NODE_DATA(early_pfn_to_nid(goal >> PAGE_SHIFT));
|
limit = goal + (1UL << PA_SECTION_SHIFT);
|
||||||
return __alloc_bootmem_node_nopanic(host_pgdat, size,
|
nid = early_pfn_to_nid(goal >> PAGE_SHIFT);
|
||||||
SMP_CACHE_BYTES, goal);
|
again:
|
||||||
|
p = ___alloc_bootmem_node_nopanic(NODE_DATA(nid), size,
|
||||||
|
SMP_CACHE_BYTES, goal, limit);
|
||||||
|
if (!p && limit) {
|
||||||
|
limit = 0;
|
||||||
|
goto again;
|
||||||
|
}
|
||||||
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __init check_usemap_section_nr(int nid, unsigned long *usemap)
|
static void __init check_usemap_section_nr(int nid, unsigned long *usemap)
|
||||||
|
|
|
@ -2955,14 +2955,17 @@ int kswapd_run(int nid)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Called by memory hotplug when all memory in a node is offlined.
|
* Called by memory hotplug when all memory in a node is offlined. Caller must
|
||||||
|
* hold lock_memory_hotplug().
|
||||||
*/
|
*/
|
||||||
void kswapd_stop(int nid)
|
void kswapd_stop(int nid)
|
||||||
{
|
{
|
||||||
struct task_struct *kswapd = NODE_DATA(nid)->kswapd;
|
struct task_struct *kswapd = NODE_DATA(nid)->kswapd;
|
||||||
|
|
||||||
if (kswapd)
|
if (kswapd) {
|
||||||
kthread_stop(kswapd);
|
kthread_stop(kswapd);
|
||||||
|
NODE_DATA(nid)->kswapd = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __init kswapd_init(void)
|
static int __init kswapd_init(void)
|
||||||
|
|
Loading…
Reference in a new issue