aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/mips/include/asm/mipsregs.h22
-rw-r--r--arch/mips/kernel/linux32.c1
-rw-r--r--arch/mips/kernel/traps.c12
-rw-r--r--arch/mips/mm/c-r4k.c2
-rw-r--r--arch/mips/mm/dma-default.c2
-rw-r--r--fs/inode.c47
-rw-r--r--fs/namespace.c11
-rw-r--r--include/linux/fs.h1
-rw-r--r--include/linux/mount.h1
-rw-r--r--mm/page-writeback.c4
10 files changed, 70 insertions, 33 deletions
diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h
index 0417516503f6..526f327475ce 100644
--- a/arch/mips/include/asm/mipsregs.h
+++ b/arch/mips/include/asm/mipsregs.h
@@ -1391,11 +1391,11 @@ static inline void tlb_write_random(void)
1391static inline unsigned int \ 1391static inline unsigned int \
1392set_c0_##name(unsigned int set) \ 1392set_c0_##name(unsigned int set) \
1393{ \ 1393{ \
1394 unsigned int res; \ 1394 unsigned int res, new; \
1395 \ 1395 \
1396 res = read_c0_##name(); \ 1396 res = read_c0_##name(); \
1397 res |= set; \ 1397 new = res | set; \
1398 write_c0_##name(res); \ 1398 write_c0_##name(new); \
1399 \ 1399 \
1400 return res; \ 1400 return res; \
1401} \ 1401} \
@@ -1403,24 +1403,24 @@ set_c0_##name(unsigned int set) \
1403static inline unsigned int \ 1403static inline unsigned int \
1404clear_c0_##name(unsigned int clear) \ 1404clear_c0_##name(unsigned int clear) \
1405{ \ 1405{ \
1406 unsigned int res; \ 1406 unsigned int res, new; \
1407 \ 1407 \
1408 res = read_c0_##name(); \ 1408 res = read_c0_##name(); \
1409 res &= ~clear; \ 1409 new = res & ~clear; \
1410 write_c0_##name(res); \ 1410 write_c0_##name(new); \
1411 \ 1411 \
1412 return res; \ 1412 return res; \
1413} \ 1413} \
1414 \ 1414 \
1415static inline unsigned int \ 1415static inline unsigned int \
1416change_c0_##name(unsigned int change, unsigned int new) \ 1416change_c0_##name(unsigned int change, unsigned int val) \
1417{ \ 1417{ \
1418 unsigned int res; \ 1418 unsigned int res, new; \
1419 \ 1419 \
1420 res = read_c0_##name(); \ 1420 res = read_c0_##name(); \
1421 res &= ~change; \ 1421 new = res & ~change; \
1422 res |= (new & change); \ 1422 new |= (val & change); \
1423 write_c0_##name(res); \ 1423 write_c0_##name(new); \
1424 \ 1424 \
1425 return res; \ 1425 return res; \
1426} 1426}
diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c
index 1a86f84fa947..49aac6e17df9 100644
--- a/arch/mips/kernel/linux32.c
+++ b/arch/mips/kernel/linux32.c
@@ -32,7 +32,6 @@
32#include <linux/module.h> 32#include <linux/module.h>
33#include <linux/binfmts.h> 33#include <linux/binfmts.h>
34#include <linux/security.h> 34#include <linux/security.h>
35#include <linux/syscalls.h>
36#include <linux/compat.h> 35#include <linux/compat.h>
37#include <linux/vfs.h> 36#include <linux/vfs.h>
38#include <linux/ipc.h> 37#include <linux/ipc.h>
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index b2d7041341b8..29fadaccecdd 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -1520,7 +1520,9 @@ void __cpuinit per_cpu_trap_init(void)
1520#endif /* CONFIG_MIPS_MT_SMTC */ 1520#endif /* CONFIG_MIPS_MT_SMTC */
1521 1521
1522 if (cpu_has_veic || cpu_has_vint) { 1522 if (cpu_has_veic || cpu_has_vint) {
1523 unsigned long sr = set_c0_status(ST0_BEV);
1523 write_c0_ebase(ebase); 1524 write_c0_ebase(ebase);
1525 write_c0_status(sr);
1524 /* Setting vector spacing enables EI/VI mode */ 1526 /* Setting vector spacing enables EI/VI mode */
1525 change_c0_intctl(0x3e0, VECTORSPACING); 1527 change_c0_intctl(0x3e0, VECTORSPACING);
1526 } 1528 }
@@ -1602,8 +1604,6 @@ void __cpuinit set_uncached_handler(unsigned long offset, void *addr,
1602#ifdef CONFIG_64BIT 1604#ifdef CONFIG_64BIT
1603 unsigned long uncached_ebase = TO_UNCAC(ebase); 1605 unsigned long uncached_ebase = TO_UNCAC(ebase);
1604#endif 1606#endif
1605 if (cpu_has_mips_r2)
1606 uncached_ebase += (read_c0_ebase() & 0x3ffff000);
1607 1607
1608 if (!addr) 1608 if (!addr)
1609 panic(panic_null_cerr); 1609 panic(panic_null_cerr);
@@ -1635,9 +1635,11 @@ void __init trap_init(void)
1635 return; /* Already done */ 1635 return; /* Already done */
1636#endif 1636#endif
1637 1637
1638 if (cpu_has_veic || cpu_has_vint) 1638 if (cpu_has_veic || cpu_has_vint) {
1639 ebase = (unsigned long) alloc_bootmem_low_pages(0x200 + VECTORSPACING*64); 1639 unsigned long size = 0x200 + VECTORSPACING*64;
1640 else { 1640 ebase = (unsigned long)
1641 __alloc_bootmem(size, 1 << fls(size), 0);
1642 } else {
1641 ebase = CAC_BASE; 1643 ebase = CAC_BASE;
1642 if (cpu_has_mips_r2) 1644 if (cpu_has_mips_r2)
1643 ebase += (read_c0_ebase() & 0x3ffff000); 1645 ebase += (read_c0_ebase() & 0x3ffff000);
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
index c43f4b26a690..871e828bc62a 100644
--- a/arch/mips/mm/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
@@ -780,7 +780,7 @@ static void __cpuinit probe_pcache(void)
780 c->dcache.ways = 2; 780 c->dcache.ways = 2;
781 c->dcache.waybit = 0; 781 c->dcache.waybit = 0;
782 782
783 c->options |= MIPS_CPU_CACHE_CDEX_P; 783 c->options |= MIPS_CPU_CACHE_CDEX_P | MIPS_CPU_PREFETCH;
784 break; 784 break;
785 785
786 case CPU_TX49XX: 786 case CPU_TX49XX:
diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c
index 546e6977d4ff..bed56f1ac837 100644
--- a/arch/mips/mm/dma-default.c
+++ b/arch/mips/mm/dma-default.c
@@ -225,7 +225,7 @@ void dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
225 if (!plat_device_is_coherent(dev) && direction != DMA_TO_DEVICE) { 225 if (!plat_device_is_coherent(dev) && direction != DMA_TO_DEVICE) {
226 unsigned long addr; 226 unsigned long addr;
227 227
228 addr = plat_dma_addr_to_phys(dma_address); 228 addr = dma_addr_to_virt(dma_address);
229 dma_cache_wback_inv(addr, size); 229 dma_cache_wback_inv(addr, size);
230 } 230 }
231 231
diff --git a/fs/inode.c b/fs/inode.c
index 8a47ccd9fc38..643ac43e5a5c 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -1300,6 +1300,40 @@ sector_t bmap(struct inode * inode, sector_t block)
1300} 1300}
1301EXPORT_SYMBOL(bmap); 1301EXPORT_SYMBOL(bmap);
1302 1302
1303/*
1304 * With relative atime, only update atime if the previous atime is
1305 * earlier than either the ctime or mtime or if at least a day has
1306 * passed since the last atime update.
1307 */
1308static int relatime_need_update(struct vfsmount *mnt, struct inode *inode,
1309 struct timespec now)
1310{
1311
1312 if (!(mnt->mnt_flags & MNT_RELATIME))
1313 return 1;
1314 /*
1315 * Is mtime younger than atime? If yes, update atime:
1316 */
1317 if (timespec_compare(&inode->i_mtime, &inode->i_atime) >= 0)
1318 return 1;
1319 /*
1320 * Is ctime younger than atime? If yes, update atime:
1321 */
1322 if (timespec_compare(&inode->i_ctime, &inode->i_atime) >= 0)
1323 return 1;
1324
1325 /*
1326 * Is the previous atime value older than a day? If yes,
1327 * update atime:
1328 */
1329 if ((long)(now.tv_sec - inode->i_atime.tv_sec) >= 24*60*60)
1330 return 1;
1331 /*
1332 * Good, we can skip the atime update:
1333 */
1334 return 0;
1335}
1336
1303/** 1337/**
1304 * touch_atime - update the access time 1338 * touch_atime - update the access time
1305 * @mnt: mount the inode is accessed on 1339 * @mnt: mount the inode is accessed on
@@ -1327,17 +1361,12 @@ void touch_atime(struct vfsmount *mnt, struct dentry *dentry)
1327 goto out; 1361 goto out;
1328 if ((mnt->mnt_flags & MNT_NODIRATIME) && S_ISDIR(inode->i_mode)) 1362 if ((mnt->mnt_flags & MNT_NODIRATIME) && S_ISDIR(inode->i_mode))
1329 goto out; 1363 goto out;
1330 if (mnt->mnt_flags & MNT_RELATIME) {
1331 /*
1332 * With relative atime, only update atime if the previous
1333 * atime is earlier than either the ctime or mtime.
1334 */
1335 if (timespec_compare(&inode->i_mtime, &inode->i_atime) < 0 &&
1336 timespec_compare(&inode->i_ctime, &inode->i_atime) < 0)
1337 goto out;
1338 }
1339 1364
1340 now = current_fs_time(inode->i_sb); 1365 now = current_fs_time(inode->i_sb);
1366
1367 if (!relatime_need_update(mnt, inode, now))
1368 goto out;
1369
1341 if (timespec_equal(&inode->i_atime, &now)) 1370 if (timespec_equal(&inode->i_atime, &now))
1342 goto out; 1371 goto out;
1343 1372
diff --git a/fs/namespace.c b/fs/namespace.c
index 06f8e63f6cb1..f0e753097353 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -780,6 +780,7 @@ static void show_mnt_opts(struct seq_file *m, struct vfsmount *mnt)
780 { MNT_NOATIME, ",noatime" }, 780 { MNT_NOATIME, ",noatime" },
781 { MNT_NODIRATIME, ",nodiratime" }, 781 { MNT_NODIRATIME, ",nodiratime" },
782 { MNT_RELATIME, ",relatime" }, 782 { MNT_RELATIME, ",relatime" },
783 { MNT_STRICTATIME, ",strictatime" },
783 { 0, NULL } 784 { 0, NULL }
784 }; 785 };
785 const struct proc_fs_info *fs_infop; 786 const struct proc_fs_info *fs_infop;
@@ -1919,6 +1920,9 @@ long do_mount(char *dev_name, char *dir_name, char *type_page,
1919 if (data_page) 1920 if (data_page)
1920 ((char *)data_page)[PAGE_SIZE - 1] = 0; 1921 ((char *)data_page)[PAGE_SIZE - 1] = 0;
1921 1922
1923 /* Default to relatime */
1924 mnt_flags |= MNT_RELATIME;
1925
1922 /* Separate the per-mountpoint flags */ 1926 /* Separate the per-mountpoint flags */
1923 if (flags & MS_NOSUID) 1927 if (flags & MS_NOSUID)
1924 mnt_flags |= MNT_NOSUID; 1928 mnt_flags |= MNT_NOSUID;
@@ -1930,13 +1934,14 @@ long do_mount(char *dev_name, char *dir_name, char *type_page,
1930 mnt_flags |= MNT_NOATIME; 1934 mnt_flags |= MNT_NOATIME;
1931 if (flags & MS_NODIRATIME) 1935 if (flags & MS_NODIRATIME)
1932 mnt_flags |= MNT_NODIRATIME; 1936 mnt_flags |= MNT_NODIRATIME;
1933 if (flags & MS_RELATIME) 1937 if (flags & MS_STRICTATIME)
1934 mnt_flags |= MNT_RELATIME; 1938 mnt_flags &= ~(MNT_RELATIME | MNT_NOATIME);
1935 if (flags & MS_RDONLY) 1939 if (flags & MS_RDONLY)
1936 mnt_flags |= MNT_READONLY; 1940 mnt_flags |= MNT_READONLY;
1937 1941
1938 flags &= ~(MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE | 1942 flags &= ~(MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE |
1939 MS_NOATIME | MS_NODIRATIME | MS_RELATIME| MS_KERNMOUNT); 1943 MS_NOATIME | MS_NODIRATIME | MS_RELATIME| MS_KERNMOUNT |
1944 MS_STRICTATIME);
1940 1945
1941 /* ... and get the mountpoint */ 1946 /* ... and get the mountpoint */
1942 retval = kern_path(dir_name, LOOKUP_FOLLOW, &path); 1947 retval = kern_path(dir_name, LOOKUP_FOLLOW, &path);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 92734c0012e6..5bc81c4a98c1 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -141,6 +141,7 @@ struct inodes_stat_t {
141#define MS_RELATIME (1<<21) /* Update atime relative to mtime/ctime. */ 141#define MS_RELATIME (1<<21) /* Update atime relative to mtime/ctime. */
142#define MS_KERNMOUNT (1<<22) /* this is a kern_mount call */ 142#define MS_KERNMOUNT (1<<22) /* this is a kern_mount call */
143#define MS_I_VERSION (1<<23) /* Update inode I_version field */ 143#define MS_I_VERSION (1<<23) /* Update inode I_version field */
144#define MS_STRICTATIME (1<<24) /* Always perform atime updates */
144#define MS_ACTIVE (1<<30) 145#define MS_ACTIVE (1<<30)
145#define MS_NOUSER (1<<31) 146#define MS_NOUSER (1<<31)
146 147
diff --git a/include/linux/mount.h b/include/linux/mount.h
index cab2a85e2ee8..51f55f903aff 100644
--- a/include/linux/mount.h
+++ b/include/linux/mount.h
@@ -27,6 +27,7 @@ struct mnt_namespace;
27#define MNT_NODIRATIME 0x10 27#define MNT_NODIRATIME 0x10
28#define MNT_RELATIME 0x20 28#define MNT_RELATIME 0x20
29#define MNT_READONLY 0x40 /* does the user want this to be r/o? */ 29#define MNT_READONLY 0x40 /* does the user want this to be r/o? */
30#define MNT_STRICTATIME 0x80
30 31
31#define MNT_SHRINKABLE 0x100 32#define MNT_SHRINKABLE 0x100
32#define MNT_IMBALANCED_WRITE_COUNT 0x200 /* just for debugging */ 33#define MNT_IMBALANCED_WRITE_COUNT 0x200 /* just for debugging */
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index 74dc57c74349..40ca7cdb653e 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -66,7 +66,7 @@ static inline long sync_writeback_pages(void)
66/* 66/*
67 * Start background writeback (via pdflush) at this percentage 67 * Start background writeback (via pdflush) at this percentage
68 */ 68 */
69int dirty_background_ratio = 5; 69int dirty_background_ratio = 10;
70 70
71/* 71/*
72 * dirty_background_bytes starts at 0 (disabled) so that it is a function of 72 * dirty_background_bytes starts at 0 (disabled) so that it is a function of
@@ -83,7 +83,7 @@ int vm_highmem_is_dirtyable;
83/* 83/*
84 * The generator of dirty data starts writeback at this percentage 84 * The generator of dirty data starts writeback at this percentage
85 */ 85 */
86int vm_dirty_ratio = 10; 86int vm_dirty_ratio = 20;
87 87
88/* 88/*
89 * vm_dirty_bytes starts at 0 (disabled) so that it is a function of 89 * vm_dirty_bytes starts at 0 (disabled) so that it is a function of