mirror of
https://github.com/linux-msm/laptops-kernel.git
synced 2026-08-13 14:19:53 -07:00
Merge branch 'akpm' (patches from Andrew)
Merge misc updates from Andrew Morton: "Bite-sized chunks this time, to avoid the MTA ratelimiting woes. - fs/notify updates - ocfs2 - some of MM" That laconic "some MM" is mainly the removal of remap_file_pages(), which is a big simplification of the VM, and which gets rid of a *lot* of random cruft and special cases because we no longer support the non-linear mappings that it used. From a user interface perspective, nothing has changed, because the remap_file_pages() syscall still exists, it's just done by emulating the old behavior by creating a lot of individual small mappings instead of one non-linear one. The emulation is slower than the old "native" non-linear mappings, but nobody really uses or cares about remap_file_pages(), and simplifying the VM is a big advantage. * emailed patches from Andrew Morton <akpm@linux-foundation.org>: (78 commits) memcg: zap memcg_slab_caches and memcg_slab_mutex memcg: zap memcg_name argument of memcg_create_kmem_cache memcg: zap __memcg_{charge,uncharge}_slab mm/page_alloc.c: place zone_id check before VM_BUG_ON_PAGE check mm: hugetlb: fix type of hugetlb_treat_as_movable variable mm, hugetlb: remove unnecessary lower bound on sysctl handlers"? mm: memory: merge shared-writable dirtying branches in do_wp_page() mm: memory: remove ->vm_file check on shared writable vmas xtensa: drop _PAGE_FILE and pte_file()-related helpers x86: drop _PAGE_FILE and pte_file()-related helpers unicore32: drop pte_file()-related helpers um: drop _PAGE_FILE and pte_file()-related helpers tile: drop pte_file()-related helpers sparc: drop pte_file()-related helpers sh: drop _PAGE_FILE and pte_file()-related helpers score: drop _PAGE_FILE and pte_file()-related helpers s390: drop pte_file()-related helpers parisc: drop _PAGE_FILE and pte_file()-related helpers openrisc: drop _PAGE_FILE and pte_file()-related helpers nios2: drop _PAGE_FILE and pte_file()-related helpers ...
This commit is contained in:
@@ -317,10 +317,10 @@ maps this page at its virtual address.
|
||||
about doing this.
|
||||
|
||||
The idea is, first at flush_dcache_page() time, if
|
||||
page->mapping->i_mmap is an empty tree and ->i_mmap_nonlinear
|
||||
an empty list, just mark the architecture private page flag bit.
|
||||
Later, in update_mmu_cache(), a check is made of this flag bit,
|
||||
and if set the flush is done and the flag bit is cleared.
|
||||
page->mapping->i_mmap is an empty tree, just mark the architecture
|
||||
private page flag bit. Later, in update_mmu_cache(), a check is
|
||||
made of this flag bit, and if set the flush is done and the flag
|
||||
bit is cleared.
|
||||
|
||||
IMPORTANT NOTE: It is often important, if you defer the flush,
|
||||
that the actual flush occurs on the same CPU
|
||||
|
||||
@@ -196,7 +196,8 @@ struct fiemap_extent_info {
|
||||
};
|
||||
|
||||
It is intended that the file system should not need to access any of this
|
||||
structure directly.
|
||||
structure directly. Filesystem handlers should be tolerant to signals and return
|
||||
EINTR once fatal signal received.
|
||||
|
||||
|
||||
Flag checking should be done at the beginning of the ->fiemap callback via the
|
||||
|
||||
@@ -4,201 +4,10 @@
|
||||
|
||||
|
||||
Document started 15 Mar 2005 by Robert Love <rml@novell.com>
|
||||
Document updated 4 Jan 2015 by Zhang Zhen <zhenzhang.zhang@huawei.com>
|
||||
--Deleted obsoleted interface, just refer to manpages for user interface.
|
||||
|
||||
|
||||
(i) User Interface
|
||||
|
||||
Inotify is controlled by a set of three system calls and normal file I/O on a
|
||||
returned file descriptor.
|
||||
|
||||
First step in using inotify is to initialise an inotify instance:
|
||||
|
||||
int fd = inotify_init ();
|
||||
|
||||
Each instance is associated with a unique, ordered queue.
|
||||
|
||||
Change events are managed by "watches". A watch is an (object,mask) pair where
|
||||
the object is a file or directory and the mask is a bit mask of one or more
|
||||
inotify events that the application wishes to receive. See <linux/inotify.h>
|
||||
for valid events. A watch is referenced by a watch descriptor, or wd.
|
||||
|
||||
Watches are added via a path to the file.
|
||||
|
||||
Watches on a directory will return events on any files inside of the directory.
|
||||
|
||||
Adding a watch is simple:
|
||||
|
||||
int wd = inotify_add_watch (fd, path, mask);
|
||||
|
||||
Where "fd" is the return value from inotify_init(), path is the path to the
|
||||
object to watch, and mask is the watch mask (see <linux/inotify.h>).
|
||||
|
||||
You can update an existing watch in the same manner, by passing in a new mask.
|
||||
|
||||
An existing watch is removed via
|
||||
|
||||
int ret = inotify_rm_watch (fd, wd);
|
||||
|
||||
Events are provided in the form of an inotify_event structure that is read(2)
|
||||
from a given inotify instance. The filename is of dynamic length and follows
|
||||
the struct. It is of size len. The filename is padded with null bytes to
|
||||
ensure proper alignment. This padding is reflected in len.
|
||||
|
||||
You can slurp multiple events by passing a large buffer, for example
|
||||
|
||||
size_t len = read (fd, buf, BUF_LEN);
|
||||
|
||||
Where "buf" is a pointer to an array of "inotify_event" structures at least
|
||||
BUF_LEN bytes in size. The above example will return as many events as are
|
||||
available and fit in BUF_LEN.
|
||||
|
||||
Each inotify instance fd is also select()- and poll()-able.
|
||||
|
||||
You can find the size of the current event queue via the standard FIONREAD
|
||||
ioctl on the fd returned by inotify_init().
|
||||
|
||||
All watches are destroyed and cleaned up on close.
|
||||
|
||||
|
||||
(ii)
|
||||
|
||||
Prototypes:
|
||||
|
||||
int inotify_init (void);
|
||||
int inotify_add_watch (int fd, const char *path, __u32 mask);
|
||||
int inotify_rm_watch (int fd, __u32 mask);
|
||||
|
||||
|
||||
(iii) Kernel Interface
|
||||
|
||||
Inotify's kernel API consists a set of functions for managing watches and an
|
||||
event callback.
|
||||
|
||||
To use the kernel API, you must first initialize an inotify instance with a set
|
||||
of inotify_operations. You are given an opaque inotify_handle, which you use
|
||||
for any further calls to inotify.
|
||||
|
||||
struct inotify_handle *ih = inotify_init(my_event_handler);
|
||||
|
||||
You must provide a function for processing events and a function for destroying
|
||||
the inotify watch.
|
||||
|
||||
void handle_event(struct inotify_watch *watch, u32 wd, u32 mask,
|
||||
u32 cookie, const char *name, struct inode *inode)
|
||||
|
||||
watch - the pointer to the inotify_watch that triggered this call
|
||||
wd - the watch descriptor
|
||||
mask - describes the event that occurred
|
||||
cookie - an identifier for synchronizing events
|
||||
name - the dentry name for affected files in a directory-based event
|
||||
inode - the affected inode in a directory-based event
|
||||
|
||||
void destroy_watch(struct inotify_watch *watch)
|
||||
|
||||
You may add watches by providing a pre-allocated and initialized inotify_watch
|
||||
structure and specifying the inode to watch along with an inotify event mask.
|
||||
You must pin the inode during the call. You will likely wish to embed the
|
||||
inotify_watch structure in a structure of your own which contains other
|
||||
information about the watch. Once you add an inotify watch, it is immediately
|
||||
subject to removal depending on filesystem events. You must grab a reference if
|
||||
you depend on the watch hanging around after the call.
|
||||
|
||||
inotify_init_watch(&my_watch->iwatch);
|
||||
inotify_get_watch(&my_watch->iwatch); // optional
|
||||
s32 wd = inotify_add_watch(ih, &my_watch->iwatch, inode, mask);
|
||||
inotify_put_watch(&my_watch->iwatch); // optional
|
||||
|
||||
You may use the watch descriptor (wd) or the address of the inotify_watch for
|
||||
other inotify operations. You must not directly read or manipulate data in the
|
||||
inotify_watch. Additionally, you must not call inotify_add_watch() more than
|
||||
once for a given inotify_watch structure, unless you have first called either
|
||||
inotify_rm_watch() or inotify_rm_wd().
|
||||
|
||||
To determine if you have already registered a watch for a given inode, you may
|
||||
call inotify_find_watch(), which gives you both the wd and the watch pointer for
|
||||
the inotify_watch, or an error if the watch does not exist.
|
||||
|
||||
wd = inotify_find_watch(ih, inode, &watchp);
|
||||
|
||||
You may use container_of() on the watch pointer to access your own data
|
||||
associated with a given watch. When an existing watch is found,
|
||||
inotify_find_watch() bumps the refcount before releasing its locks. You must
|
||||
put that reference with:
|
||||
|
||||
put_inotify_watch(watchp);
|
||||
|
||||
Call inotify_find_update_watch() to update the event mask for an existing watch.
|
||||
inotify_find_update_watch() returns the wd of the updated watch, or an error if
|
||||
the watch does not exist.
|
||||
|
||||
wd = inotify_find_update_watch(ih, inode, mask);
|
||||
|
||||
An existing watch may be removed by calling either inotify_rm_watch() or
|
||||
inotify_rm_wd().
|
||||
|
||||
int ret = inotify_rm_watch(ih, &my_watch->iwatch);
|
||||
int ret = inotify_rm_wd(ih, wd);
|
||||
|
||||
A watch may be removed while executing your event handler with the following:
|
||||
|
||||
inotify_remove_watch_locked(ih, iwatch);
|
||||
|
||||
Call inotify_destroy() to remove all watches from your inotify instance and
|
||||
release it. If there are no outstanding references, inotify_destroy() will call
|
||||
your destroy_watch op for each watch.
|
||||
|
||||
inotify_destroy(ih);
|
||||
|
||||
When inotify removes a watch, it sends an IN_IGNORED event to your callback.
|
||||
You may use this event as an indication to free the watch memory. Note that
|
||||
inotify may remove a watch due to filesystem events, as well as by your request.
|
||||
If you use IN_ONESHOT, inotify will remove the watch after the first event, at
|
||||
which point you may call the final inotify_put_watch.
|
||||
|
||||
(iv) Kernel Interface Prototypes
|
||||
|
||||
struct inotify_handle *inotify_init(struct inotify_operations *ops);
|
||||
|
||||
inotify_init_watch(struct inotify_watch *watch);
|
||||
|
||||
s32 inotify_add_watch(struct inotify_handle *ih,
|
||||
struct inotify_watch *watch,
|
||||
struct inode *inode, u32 mask);
|
||||
|
||||
s32 inotify_find_watch(struct inotify_handle *ih, struct inode *inode,
|
||||
struct inotify_watch **watchp);
|
||||
|
||||
s32 inotify_find_update_watch(struct inotify_handle *ih,
|
||||
struct inode *inode, u32 mask);
|
||||
|
||||
int inotify_rm_wd(struct inotify_handle *ih, u32 wd);
|
||||
|
||||
int inotify_rm_watch(struct inotify_handle *ih,
|
||||
struct inotify_watch *watch);
|
||||
|
||||
void inotify_remove_watch_locked(struct inotify_handle *ih,
|
||||
struct inotify_watch *watch);
|
||||
|
||||
void inotify_destroy(struct inotify_handle *ih);
|
||||
|
||||
void get_inotify_watch(struct inotify_watch *watch);
|
||||
void put_inotify_watch(struct inotify_watch *watch);
|
||||
|
||||
|
||||
(v) Internal Kernel Implementation
|
||||
|
||||
Each inotify instance is represented by an inotify_handle structure.
|
||||
Inotify's userspace consumers also have an inotify_device which is
|
||||
associated with the inotify_handle, and on which events are queued.
|
||||
|
||||
Each watch is associated with an inotify_watch structure. Watches are chained
|
||||
off of each associated inotify_handle and each associated inode.
|
||||
|
||||
See fs/notify/inotify/inotify_fsnotify.c and fs/notify/inotify/inotify_user.c
|
||||
for the locking and lifetime rules.
|
||||
|
||||
|
||||
(vi) Rationale
|
||||
(i) Rationale
|
||||
|
||||
Q: What is the design decision behind not tying the watch to the open fd of
|
||||
the watched object?
|
||||
|
||||
@@ -100,3 +100,7 @@ coherency=full (*) Disallow concurrent O_DIRECT writes, cluster inode
|
||||
coherency=buffered Allow concurrent O_DIRECT writes without EX lock among
|
||||
nodes, which gains high performance at risk of getting
|
||||
stale data on other nodes.
|
||||
journal_async_commit Commit block can be written to disk without waiting
|
||||
for descriptor blocks. If enabled older kernels cannot
|
||||
mount the device. This will enable 'journal_checksum'
|
||||
internally.
|
||||
|
||||
@@ -18,10 +18,9 @@ on 32-bit systems to map files bigger than can linearly fit into 32-bit
|
||||
virtual address space. This use-case is not critical anymore since 64-bit
|
||||
systems are widely available.
|
||||
|
||||
The plan is to deprecate the syscall and replace it with an emulation.
|
||||
The emulation will create new VMAs instead of nonlinear mappings. It's
|
||||
going to work slower for rare users of remap_file_pages() but ABI is
|
||||
preserved.
|
||||
The syscall is deprecated and replaced it with an emulation now. The
|
||||
emulation creates new VMAs instead of nonlinear mappings. It's going to
|
||||
work slower for rare users of remap_file_pages() but ABI is preserved.
|
||||
|
||||
One side effect of emulation (apart from performance) is that user can hit
|
||||
vm.max_map_count limit more easily due to additional VMAs. See comment for
|
||||
|
||||
@@ -73,7 +73,6 @@ struct vm_area_struct;
|
||||
/* .. and these are ours ... */
|
||||
#define _PAGE_DIRTY 0x20000
|
||||
#define _PAGE_ACCESSED 0x40000
|
||||
#define _PAGE_FILE 0x80000 /* set:pagecache, unset:swap */
|
||||
|
||||
/*
|
||||
* NOTE! The "accessed" bit isn't necessarily exact: it can be kept exactly
|
||||
@@ -268,7 +267,6 @@ extern inline void pgd_clear(pgd_t * pgdp) { pgd_val(*pgdp) = 0; }
|
||||
extern inline int pte_write(pte_t pte) { return !(pte_val(pte) & _PAGE_FOW); }
|
||||
extern inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; }
|
||||
extern inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; }
|
||||
extern inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE; }
|
||||
extern inline int pte_special(pte_t pte) { return 0; }
|
||||
|
||||
extern inline pte_t pte_wrprotect(pte_t pte) { pte_val(pte) |= _PAGE_FOW; return pte; }
|
||||
@@ -345,11 +343,6 @@ extern inline pte_t mk_swap_pte(unsigned long type, unsigned long offset)
|
||||
#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
|
||||
#define __swp_entry_to_pte(x) ((pte_t) { (x).val })
|
||||
|
||||
#define pte_to_pgoff(pte) (pte_val(pte) >> 32)
|
||||
#define pgoff_to_pte(off) ((pte_t) { ((off) << 32) | _PAGE_FILE })
|
||||
|
||||
#define PTE_FILE_MAX_BITS 32
|
||||
|
||||
#ifndef CONFIG_DISCONTIGMEM
|
||||
#define kern_addr_valid(addr) (1)
|
||||
#endif
|
||||
|
||||
@@ -61,7 +61,6 @@
|
||||
#define _PAGE_WRITE (1<<4) /* Page has user write perm (H) */
|
||||
#define _PAGE_READ (1<<5) /* Page has user read perm (H) */
|
||||
#define _PAGE_MODIFIED (1<<6) /* Page modified (dirty) (S) */
|
||||
#define _PAGE_FILE (1<<7) /* page cache/ swap (S) */
|
||||
#define _PAGE_GLOBAL (1<<8) /* Page is global (H) */
|
||||
#define _PAGE_PRESENT (1<<10) /* TLB entry is valid (H) */
|
||||
|
||||
@@ -73,7 +72,6 @@
|
||||
#define _PAGE_READ (1<<3) /* Page has user read perm (H) */
|
||||
#define _PAGE_ACCESSED (1<<4) /* Page is accessed (S) */
|
||||
#define _PAGE_MODIFIED (1<<5) /* Page modified (dirty) (S) */
|
||||
#define _PAGE_FILE (1<<6) /* page cache/ swap (S) */
|
||||
#define _PAGE_GLOBAL (1<<8) /* Page is global (H) */
|
||||
#define _PAGE_PRESENT (1<<9) /* TLB entry is valid (H) */
|
||||
#define _PAGE_SHARED_CODE (1<<11) /* Shared Code page with cmn vaddr
|
||||
@@ -268,15 +266,6 @@ static inline void pmd_set(pmd_t *pmdp, pte_t *ptep)
|
||||
pte; \
|
||||
})
|
||||
|
||||
/* TBD: Non linear mapping stuff */
|
||||
static inline int pte_file(pte_t pte)
|
||||
{
|
||||
return pte_val(pte) & _PAGE_FILE;
|
||||
}
|
||||
|
||||
#define PTE_FILE_MAX_BITS 30
|
||||
#define pgoff_to_pte(x) __pte(x)
|
||||
#define pte_to_pgoff(x) (pte_val(x) >> 2)
|
||||
#define pte_pfn(pte) (pte_val(pte) >> PAGE_SHIFT)
|
||||
#define pfn_pte(pfn, prot) (__pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot)))
|
||||
#define __pte_index(addr) (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
|
||||
@@ -364,7 +353,7 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address,
|
||||
|
||||
/* Encode swap {type,off} tuple into PTE
|
||||
* We reserve 13 bits for 5-bit @type, keeping bits 12-5 zero, ensuring that
|
||||
* both PAGE_FILE and PAGE_PRESENT are zero in a PTE holding swap "identifier"
|
||||
* PAGE_PRESENT is zero in a PTE holding swap "identifier"
|
||||
*/
|
||||
#define __swp_entry(type, off) ((swp_entry_t) { \
|
||||
((type) & 0x1f) | ((off) << 13) })
|
||||
|
||||
@@ -118,7 +118,6 @@
|
||||
#define L_PTE_VALID (_AT(pteval_t, 1) << 0) /* Valid */
|
||||
#define L_PTE_PRESENT (_AT(pteval_t, 1) << 0)
|
||||
#define L_PTE_YOUNG (_AT(pteval_t, 1) << 1)
|
||||
#define L_PTE_FILE (_AT(pteval_t, 1) << 2) /* only when !PRESENT */
|
||||
#define L_PTE_DIRTY (_AT(pteval_t, 1) << 6)
|
||||
#define L_PTE_RDONLY (_AT(pteval_t, 1) << 7)
|
||||
#define L_PTE_USER (_AT(pteval_t, 1) << 8)
|
||||
|
||||
@@ -77,7 +77,6 @@
|
||||
*/
|
||||
#define L_PTE_VALID (_AT(pteval_t, 1) << 0) /* Valid */
|
||||
#define L_PTE_PRESENT (_AT(pteval_t, 3) << 0) /* Present */
|
||||
#define L_PTE_FILE (_AT(pteval_t, 1) << 2) /* only when !PRESENT */
|
||||
#define L_PTE_USER (_AT(pteval_t, 1) << 6) /* AP[1] */
|
||||
#define L_PTE_SHARED (_AT(pteval_t, 3) << 8) /* SH[1:0], inner shareable */
|
||||
#define L_PTE_YOUNG (_AT(pteval_t, 1) << 10) /* AF */
|
||||
|
||||
@@ -54,8 +54,6 @@
|
||||
|
||||
typedef pte_t *pte_addr_t;
|
||||
|
||||
static inline int pte_file(pte_t pte) { return 0; }
|
||||
|
||||
/*
|
||||
* ZERO_PAGE is a global shared page that is always zero: used
|
||||
* for zero-mapped memory areas etc..
|
||||
|
||||
@@ -318,12 +318,12 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
|
||||
*
|
||||
* 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
|
||||
* 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
|
||||
* <--------------- offset ----------------------> < type -> 0 0 0
|
||||
* <--------------- offset ------------------------> < type -> 0 0
|
||||
*
|
||||
* This gives us up to 31 swap files and 64GB per swap file. Note that
|
||||
* This gives us up to 31 swap files and 128GB per swap file. Note that
|
||||
* the offset field is always non-zero.
|
||||
*/
|
||||
#define __SWP_TYPE_SHIFT 3
|
||||
#define __SWP_TYPE_SHIFT 2
|
||||
#define __SWP_TYPE_BITS 5
|
||||
#define __SWP_TYPE_MASK ((1 << __SWP_TYPE_BITS) - 1)
|
||||
#define __SWP_OFFSET_SHIFT (__SWP_TYPE_BITS + __SWP_TYPE_SHIFT)
|
||||
@@ -342,20 +342,6 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
|
||||
*/
|
||||
#define MAX_SWAPFILES_CHECK() BUILD_BUG_ON(MAX_SWAPFILES_SHIFT > __SWP_TYPE_BITS)
|
||||
|
||||
/*
|
||||
* Encode and decode a file entry. File entries are stored in the Linux
|
||||
* page tables as follows:
|
||||
*
|
||||
* 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
|
||||
* 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
|
||||
* <----------------------- offset ------------------------> 1 0 0
|
||||
*/
|
||||
#define pte_file(pte) (pte_val(pte) & L_PTE_FILE)
|
||||
#define pte_to_pgoff(x) (pte_val(x) >> 3)
|
||||
#define pgoff_to_pte(x) __pte(((x) << 3) | L_PTE_FILE)
|
||||
|
||||
#define PTE_FILE_MAX_BITS 29
|
||||
|
||||
/* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
|
||||
/* FIXME: this is not correct */
|
||||
#define kern_addr_valid(addr) (1)
|
||||
|
||||
@@ -98,7 +98,7 @@
|
||||
#endif
|
||||
#if !defined (CONFIG_ARM_LPAE) && \
|
||||
(L_PTE_XN+L_PTE_USER+L_PTE_RDONLY+L_PTE_DIRTY+L_PTE_YOUNG+\
|
||||
L_PTE_FILE+L_PTE_PRESENT) > L_PTE_SHARED
|
||||
L_PTE_PRESENT) > L_PTE_SHARED
|
||||
#error Invalid Linux PTE bit settings
|
||||
#endif
|
||||
#endif /* CONFIG_MMU */
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
* Software defined PTE bits definition.
|
||||
*/
|
||||
#define PTE_VALID (_AT(pteval_t, 1) << 0)
|
||||
#define PTE_FILE (_AT(pteval_t, 1) << 2) /* only when !pte_present() */
|
||||
#define PTE_DIRTY (_AT(pteval_t, 1) << 55)
|
||||
#define PTE_SPECIAL (_AT(pteval_t, 1) << 56)
|
||||
#define PTE_WRITE (_AT(pteval_t, 1) << 57)
|
||||
@@ -469,13 +468,12 @@ extern pgd_t idmap_pg_dir[PTRS_PER_PGD];
|
||||
/*
|
||||
* Encode and decode a swap entry:
|
||||
* bits 0-1: present (must be zero)
|
||||
* bit 2: PTE_FILE
|
||||
* bits 3-8: swap type
|
||||
* bits 9-57: swap offset
|
||||
* bits 2-7: swap type
|
||||
* bits 8-57: swap offset
|
||||
*/
|
||||
#define __SWP_TYPE_SHIFT 3
|
||||
#define __SWP_TYPE_SHIFT 2
|
||||
#define __SWP_TYPE_BITS 6
|
||||
#define __SWP_OFFSET_BITS 49
|
||||
#define __SWP_OFFSET_BITS 50
|
||||
#define __SWP_TYPE_MASK ((1 << __SWP_TYPE_BITS) - 1)
|
||||
#define __SWP_OFFSET_SHIFT (__SWP_TYPE_BITS + __SWP_TYPE_SHIFT)
|
||||
#define __SWP_OFFSET_MASK ((1UL << __SWP_OFFSET_BITS) - 1)
|
||||
@@ -493,18 +491,6 @@ extern pgd_t idmap_pg_dir[PTRS_PER_PGD];
|
||||
*/
|
||||
#define MAX_SWAPFILES_CHECK() BUILD_BUG_ON(MAX_SWAPFILES_SHIFT > __SWP_TYPE_BITS)
|
||||
|
||||
/*
|
||||
* Encode and decode a file entry:
|
||||
* bits 0-1: present (must be zero)
|
||||
* bit 2: PTE_FILE
|
||||
* bits 3-57: file offset / PAGE_SIZE
|
||||
*/
|
||||
#define pte_file(pte) (pte_val(pte) & PTE_FILE)
|
||||
#define pte_to_pgoff(x) (pte_val(x) >> 3)
|
||||
#define pgoff_to_pte(x) __pte(((x) << 3) | PTE_FILE)
|
||||
|
||||
#define PTE_FILE_MAX_BITS 55
|
||||
|
||||
extern int kern_addr_valid(unsigned long addr);
|
||||
|
||||
#include <asm-generic/pgtable.h>
|
||||
|
||||
@@ -86,9 +86,6 @@ extern struct page *empty_zero_page;
|
||||
#define _PAGE_BIT_PRESENT 10
|
||||
#define _PAGE_BIT_ACCESSED 11 /* software: page was accessed */
|
||||
|
||||
/* The following flags are only valid when !PRESENT */
|
||||
#define _PAGE_BIT_FILE 0 /* software: pagecache or swap? */
|
||||
|
||||
#define _PAGE_WT (1 << _PAGE_BIT_WT)
|
||||
#define _PAGE_DIRTY (1 << _PAGE_BIT_DIRTY)
|
||||
#define _PAGE_EXECUTE (1 << _PAGE_BIT_EXECUTE)
|
||||
@@ -101,7 +98,6 @@ extern struct page *empty_zero_page;
|
||||
/* Software flags */
|
||||
#define _PAGE_ACCESSED (1 << _PAGE_BIT_ACCESSED)
|
||||
#define _PAGE_PRESENT (1 << _PAGE_BIT_PRESENT)
|
||||
#define _PAGE_FILE (1 << _PAGE_BIT_FILE)
|
||||
|
||||
/*
|
||||
* Page types, i.e. sizes. _PAGE_TYPE_NONE corresponds to what is
|
||||
@@ -210,14 +206,6 @@ static inline int pte_special(pte_t pte)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* The following only work if pte_present() is not true.
|
||||
*/
|
||||
static inline int pte_file(pte_t pte)
|
||||
{
|
||||
return pte_val(pte) & _PAGE_FILE;
|
||||
}
|
||||
|
||||
/* Mutator functions for PTE bits */
|
||||
static inline pte_t pte_wrprotect(pte_t pte)
|
||||
{
|
||||
@@ -329,7 +317,6 @@ extern void update_mmu_cache(struct vm_area_struct * vma,
|
||||
* Encode and decode a swap entry
|
||||
*
|
||||
* Constraints:
|
||||
* _PAGE_FILE at bit 0
|
||||
* _PAGE_TYPE_* at bits 2-3 (for emulating _PAGE_PROTNONE)
|
||||
* _PAGE_PRESENT at bit 10
|
||||
*
|
||||
@@ -346,18 +333,6 @@ extern void update_mmu_cache(struct vm_area_struct * vma,
|
||||
#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
|
||||
#define __swp_entry_to_pte(x) ((pte_t) { (x).val })
|
||||
|
||||
/*
|
||||
* Encode and decode a nonlinear file mapping entry. We have to
|
||||
* preserve _PAGE_FILE and _PAGE_PRESENT here. _PAGE_TYPE_* isn't
|
||||
* necessary, since _PAGE_FILE implies !_PAGE_PROTNONE (?)
|
||||
*/
|
||||
#define PTE_FILE_MAX_BITS 30
|
||||
#define pte_to_pgoff(pte) (((pte_val(pte) >> 1) & 0x1ff) \
|
||||
| ((pte_val(pte) >> 11) << 9))
|
||||
#define pgoff_to_pte(off) ((pte_t) { ((((off) & 0x1ff) << 1) \
|
||||
| (((off) >> 9) << 11) \
|
||||
| _PAGE_FILE) })
|
||||
|
||||
typedef pte_t *pte_addr_t;
|
||||
|
||||
#define kern_addr_valid(addr) (1)
|
||||
|
||||
@@ -45,11 +45,6 @@ extern void paging_init(void);
|
||||
#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
|
||||
#define __swp_entry_to_pte(x) ((pte_t) { (x).val })
|
||||
|
||||
static inline int pte_file(pte_t pte)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define set_pte(pteptr, pteval) (*(pteptr) = pteval)
|
||||
#define set_pte_at(mm, addr, ptep, pteval) set_pte(ptep, pteval)
|
||||
|
||||
|
||||
@@ -50,11 +50,6 @@ extern void paging_init(void);
|
||||
#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
|
||||
#define __swp_entry_to_pte(x) ((pte_t) { (x).val })
|
||||
|
||||
static inline int pte_file(pte_t pte)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define set_pte(pteptr, pteval) (*(pteptr) = pteval)
|
||||
#define set_pte_at(mm, addr, ptep, pteval) set_pte(ptep, pteval)
|
||||
|
||||
|
||||
@@ -58,7 +58,6 @@ typedef struct
|
||||
/* Bits the HW doesn't care about but the kernel uses them in SW */
|
||||
|
||||
#define _PAGE_PRESENT (1<<4) /* page present in memory */
|
||||
#define _PAGE_FILE (1<<5) /* set: pagecache, unset: swap (when !PRESENT) */
|
||||
#define _PAGE_ACCESSED (1<<5) /* simulated in software using valid bit */
|
||||
#define _PAGE_MODIFIED (1<<6) /* simulated in software using we bit */
|
||||
#define _PAGE_READ (1<<7) /* read-enabled */
|
||||
@@ -105,6 +104,4 @@ typedef struct
|
||||
#define __S110 PAGE_SHARED
|
||||
#define __S111 PAGE_SHARED
|
||||
|
||||
#define PTE_FILE_MAX_BITS 26
|
||||
|
||||
#endif
|
||||
|
||||
@@ -53,7 +53,6 @@ typedef struct
|
||||
* software.
|
||||
*/
|
||||
#define _PAGE_PRESENT (1 << 5) /* Page is present in memory. */
|
||||
#define _PAGE_FILE (1 << 6) /* 1=pagecache, 0=swap (when !present) */
|
||||
#define _PAGE_ACCESSED (1 << 6) /* Simulated in software using valid bit. */
|
||||
#define _PAGE_MODIFIED (1 << 7) /* Simulated in software using we bit. */
|
||||
#define _PAGE_READ (1 << 8) /* Read enabled. */
|
||||
@@ -108,6 +107,4 @@ typedef struct
|
||||
#define __S110 PAGE_SHARED_EXEC
|
||||
#define __S111 PAGE_SHARED_EXEC
|
||||
|
||||
#define PTE_FILE_MAX_BITS 25
|
||||
|
||||
#endif /* _ASM_CRIS_ARCH_MMU_H */
|
||||
|
||||
@@ -114,7 +114,6 @@ extern unsigned long empty_zero_page;
|
||||
static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_WRITE; }
|
||||
static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_MODIFIED; }
|
||||
static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; }
|
||||
static inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE; }
|
||||
static inline int pte_special(pte_t pte) { return 0; }
|
||||
|
||||
static inline pte_t pte_wrprotect(pte_t pte)
|
||||
@@ -290,9 +289,6 @@ static inline void update_mmu_cache(struct vm_area_struct * vma,
|
||||
*/
|
||||
#define pgtable_cache_init() do { } while (0)
|
||||
|
||||
#define pte_to_pgoff(x) (pte_val(x) >> 6)
|
||||
#define pgoff_to_pte(x) __pte(((x) << 6) | _PAGE_FILE)
|
||||
|
||||
typedef pte_t *pte_addr_t;
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
@@ -62,10 +62,6 @@ typedef pte_t *pte_addr_t;
|
||||
#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
|
||||
#define __swp_entry_to_pte(x) ((pte_t) { (x).val })
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
static inline int pte_file(pte_t pte) { return 0; }
|
||||
#endif
|
||||
|
||||
#define ZERO_PAGE(vaddr) ({ BUG(); NULL; })
|
||||
|
||||
#define swapper_pg_dir ((pgd_t *) NULL)
|
||||
@@ -298,7 +294,6 @@ static inline pmd_t *pmd_offset(pud_t *dir, unsigned long address)
|
||||
|
||||
#define _PAGE_RESERVED_MASK (xAMPRx_RESERVED8 | xAMPRx_RESERVED13)
|
||||
|
||||
#define _PAGE_FILE 0x002 /* set:pagecache unset:swap */
|
||||
#define _PAGE_PROTNONE 0x000 /* If not present */
|
||||
|
||||
#define _PAGE_CHG_MASK (PTE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
|
||||
@@ -463,27 +458,15 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
|
||||
* Handle swap and file entries
|
||||
* - the PTE is encoded in the following format:
|
||||
* bit 0: Must be 0 (!_PAGE_PRESENT)
|
||||
* bit 1: Type: 0 for swap, 1 for file (_PAGE_FILE)
|
||||
* bits 2-7: Swap type
|
||||
* bits 8-31: Swap offset
|
||||
* bits 2-31: File pgoff
|
||||
* bits 1-6: Swap type
|
||||
* bits 7-31: Swap offset
|
||||
*/
|
||||
#define __swp_type(x) (((x).val >> 2) & 0x1f)
|
||||
#define __swp_offset(x) ((x).val >> 8)
|
||||
#define __swp_entry(type, offset) ((swp_entry_t) { ((type) << 2) | ((offset) << 8) })
|
||||
#define __swp_type(x) (((x).val >> 1) & 0x1f)
|
||||
#define __swp_offset(x) ((x).val >> 7)
|
||||
#define __swp_entry(type, offset) ((swp_entry_t) { ((type) << 1) | ((offset) << 7) })
|
||||
#define __pte_to_swp_entry(_pte) ((swp_entry_t) { (_pte).pte })
|
||||
#define __swp_entry_to_pte(x) ((pte_t) { (x).val })
|
||||
|
||||
static inline int pte_file(pte_t pte)
|
||||
{
|
||||
return pte.pte & _PAGE_FILE;
|
||||
}
|
||||
|
||||
#define PTE_FILE_MAX_BITS 29
|
||||
|
||||
#define pte_to_pgoff(PTE) ((PTE).pte >> 2)
|
||||
#define pgoff_to_pte(off) __pte((off) << 2 | _PAGE_FILE)
|
||||
|
||||
/* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
|
||||
#define PageSkip(page) (0)
|
||||
#define kern_addr_valid(addr) (1)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user