Data Structures | |
| struct | cl_page |
| Fields are protected by the lock on cfs_page_t, except for atomics and immutables. More... | |
| struct | cl_page_slice |
| Per-layer part of cl_page. More... | |
| struct | cl_page_operations |
| Per-layer page operations. More... | |
| struct | cl_page |
| Fields are protected by the lock on cfs_page_t, except for atomics and immutables. More... | |
ownership | |
| Functions dealing with the ownership of page by io. | |
| int | cl_page_own (const struct lu_env *env, struct cl_io *io, struct cl_page *page) |
| Own a page, might be blocked. | |
| int | cl_page_own_try (const struct lu_env *env, struct cl_io *io, struct cl_page *page) |
| Nonblock version of cl_page_own(). | |
| void | cl_page_assume (const struct lu_env *env, struct cl_io *io, struct cl_page *page) |
| Assume page ownership. | |
| void | cl_page_unassume (const struct lu_env *env, struct cl_io *io, struct cl_page *pg) |
| Releases page ownership without unlocking the page. | |
| void | cl_page_disown (const struct lu_env *env, struct cl_io *io, struct cl_page *page) |
| Releases page ownership. | |
| int | cl_page_is_owned (const struct cl_page *pg, const struct cl_io *io) |
| returns true, iff page is owned by the given io. | |
transfer | |
| Functions dealing with the preparation of a page for a transfer, and tracking transfer state. | |
| int | cl_page_prep (const struct lu_env *env, struct cl_io *io, struct cl_page *pg, enum cl_req_type crt) |
| Prepares page for immediate transfer. | |
| void | cl_page_completion (const struct lu_env *env, struct cl_page *pg, enum cl_req_type crt, int ioret) |
| Notify layers about transfer completion. | |
| int | cl_page_make_ready (const struct lu_env *env, struct cl_page *pg, enum cl_req_type crt) |
| Notify layers that transfer formation engine decided to yank this page from the cache and to make it a part of a transfer. | |
| int | cl_page_cache_add (const struct lu_env *env, struct cl_io *io, struct cl_page *pg, enum cl_req_type crt) |
| Notify layers that high level io decided to place this page into a cache for future transfer. | |
| void | cl_page_clip (const struct lu_env *env, struct cl_page *pg, int from, int to) |
| Tells transfer engine that only part of a page is to be transmitted. | |
| int | cl_page_cancel (const struct lu_env *env, struct cl_page *page) |
| Cancel a page which is still in a transfer. | |
helper routines | |
| Functions to discard, delete and export a cl_page. | |
| void | cl_page_discard (const struct lu_env *env, struct cl_io *io, struct cl_page *pg) |
| Called when page is to be removed from the object, e.g., as a result of truncate. | |
| void | cl_page_delete (const struct lu_env *env, struct cl_page *pg) |
| Called when a decision is made to throw page out of memory. | |
| int | cl_page_unmap (const struct lu_env *env, struct cl_io *io, struct cl_page *pg) |
| Unmaps page from user virtual memory. | |
| int | cl_page_is_vmlocked (const struct lu_env *env, const struct cl_page *pg) |
| Returns true, iff pg is VM locked in a suitable sense by the calling thread. | |
| void | cl_page_export (const struct lu_env *env, struct cl_page *pg, int uptodate) |
| Marks page up-to-date. | |
| int | cl_page_is_under_lock (const struct lu_env *env, struct cl_io *io, struct cl_page *page) |
| Checks whether page is protected by any extent lock is at least required mode. | |
| loff_t | cl_offset (const struct cl_object *obj, pgoff_t idx) |
| Converts a byte offset within object obj into a page index. | |
| pgoff_t | cl_index (const struct cl_object *obj, loff_t offset) |
| Converts a page index into a byte offset within object obj. | |
| int | cl_page_size (const struct cl_object *obj) |
| int | cl_pages_prune (const struct lu_env *env, struct cl_object *obj) |
| Purges all cached pages belonging to the object obj. | |
| void | cl_lock_print (const struct lu_env *env, void *cookie, lu_printer_t printer, const struct cl_lock *lock) |
| Prints human readable representation of lock to the f. | |
| void | cl_lock_descr_print (const struct lu_env *env, void *cookie, lu_printer_t printer, const struct cl_lock_descr *descr) |
| Prints human readable representation of a lock description. | |
Defines | |
| #define | CL_PAGE_DEBUG(mask, env, page, format,) |
| Helper macro, dumping detailed information about page into a log. | |
| #define | CL_PAGE_HEADER(mask, env, page, format,) |
| Helper macro, dumping shorter information about page into a log. | |
Enumerations | |
| enum | cl_page_state { CPS_CACHED, CPS_OWNED, CPS_PAGEOUT, CPS_PAGEIN, CPS_FREEING, CPS_NR } |
| States of cl_page. More... | |
| enum | cl_page_type { CPT_CACHEABLE = 1, CPT_TRANSIENT } |
| enum | cl_page_flags { CPF_READ_COMPLETED = 1 << 0 } |
| Flags maintained for every cl_page. More... | |
Functions | |
| cl_page * | cl_page_lookup (struct cl_object_header *hdr, pgoff_t index) |
| Returns a page with given index in the given object, or NULL if no page is found. | |
| void | cl_page_gang_lookup (const struct lu_env *env, struct cl_object *obj, struct cl_io *io, pgoff_t start, pgoff_t end, struct cl_page_list *plist, int nonblock, int *resched) |
| Returns a list of pages by a given [start, end] of obj. | |
| cl_page * | cl_page_find (const struct lu_env *env, struct cl_object *obj, pgoff_t idx, struct page *vmpage, enum cl_page_type type) |
| cl_page * | cl_page_find_sub (const struct lu_env *env, struct cl_object *obj, pgoff_t idx, struct page *vmpage, struct cl_page *parent) |
| void | cl_page_get (struct cl_page *page) |
| Acquires an additional reference to a page. | |
| void | cl_page_put (const struct lu_env *env, struct cl_page *page) |
| Releases a reference to a page. | |
| void | cl_page_print (const struct lu_env *env, void *cookie, lu_printer_t printer, const struct cl_page *pg) |
| Prints human readable representation of pg to the f. | |
| void | cl_page_header_print (const struct lu_env *env, void *cookie, lu_printer_t printer, const struct cl_page *pg) |
| Prints human readable representation of pg to the f. | |
| cfs_page_t * | cl_page_vmpage (const struct lu_env *env, struct cl_page *page) |
| Returns a VM page associated with a given cl_page. | |
| cl_page * | cl_vmpage_page (cfs_page_t *vmpage, struct cl_object *obj) |
| Returns a cl_page associated with a VM page, and given cl_object. | |
| cl_page * | cl_page_top (struct cl_page *page) |
| Returns the top-page for a given page. | |
| int | cl_is_page (const void *addr) |
| Returns true if addr is an address of an allocated cl_page. | |
| cl_page_slice * | cl_page_at (const struct cl_page *page, const struct lu_device_type *dtype) |
| #define CL_PAGE_DEBUG | ( | mask, | |||
| env, | |||||
| page, | |||||
| format | ) |
Value:
do { \ static DECLARE_LU_CDEBUG_PRINT_INFO(__info, mask); \ \ if (cfs_cdebug_show(mask, DEBUG_SUBSYSTEM)) { \ cl_page_print(env, &__info, lu_cdebug_printer, page); \ CDEBUG(mask, format , ## __VA_ARGS__); \ } \ } while (0)
| #define CL_PAGE_HEADER | ( | mask, | |||
| env, | |||||
| page, | |||||
| format | ) |
Value:
do { \ static DECLARE_LU_CDEBUG_PRINT_INFO(__info, mask); \ \ if (cfs_cdebug_show(mask, DEBUG_SUBSYSTEM)) { \ cl_page_header_print(env, &__info, lu_cdebug_printer, page); \ CDEBUG(mask, format , ## __VA_ARGS__); \ } \ } while (0)
| enum cl_page_flags |
Flags maintained for every cl_page.
| enum cl_page_state |
States of cl_page.
cl_page.c assumes particular order here.
The page state machine is rather crude, as it doesn't recognize finer page states like "dirty" or "up to date". This is because such states are not always well defined for the whole stack (see, for example, the implementation of the read-ahead, that hides page up-to-dateness to track cache hits accurately). Such sub-states are maintained by the layers that are interested in them.
| CPS_CACHED |
Page is in the cache, un-owned.
Page leaves cached state in the following cases:
|
| CPS_OWNED |
Page is exclusively owned by some cl_io.
Page may end up in this state as a result of
Page leaves owned state in the following cases:
|
| CPS_PAGEOUT |
Page is being written out, as a part of a transfer.
This state is entered when req-formation logic decided that it wants this page to be sent through the wire _now_. Specifically, it means that once this state is achieved, transfer completion handler (with either success or failure indication) is guaranteed to be executed against this page independently of any locks and any scheduling decisions made by the hosting environment (that effectively means that the page is never put into cl_page_state::CPS_PAGEOUT state "in advance". This property is mentioned, because it is important when reasoning about possible dead-locks in the system). The page can enter this state as a result of
The page leaves cl_page_state::CPS_PAGEOUT state when the transfer is completed---it is moved into cl_page_state::CPS_CACHED state. Underlying VM page is locked for the duration of transfer.
|
| CPS_PAGEIN |
Page is being read in, as a part of a transfer.
This is quite similar to the cl_page_state::CPS_PAGEOUT state, except that read-in is always "immediate"---there is no such thing a sudden construction of read cl_req from cached, presumably not up to date, pages. Underlying VM page is locked for the duration of transfer.
|
| CPS_FREEING |
Page is being destroyed.
This state is entered when client decides that page has to be deleted from its host object, as, e.g., a part of truncate. Once this state is reached, there is no way to escape it.
|
| enum cl_page_type |
| int cl_is_page | ( | const void * | addr | ) |
Returns true if addr is an address of an allocated cl_page.
Used in assertions. This check is optimistically imprecise, i.e., it occasionally returns true for the incorrect addresses, but if it returns false, then the address is guaranteed to be incorrect. (Should be named cl_pagep().)
Assume page ownership.
Called when page is already locked by the hosting VM.
| int cl_page_cache_add | ( | const struct lu_env * | env, | |
| struct cl_io * | io, | |||
| struct cl_page * | pg, | |||
| enum cl_req_type | crt | |||
| ) |
Notify layers that high level io decided to place this page into a cache for future transfer.
The layer implementing transfer engine (osc) has to register this page in its queues.
Tells transfer engine that only part of a page is to be transmitted.
| void cl_page_completion | ( | const struct lu_env * | env, | |
| struct cl_page * | pg, | |||
| enum cl_req_type | crt, | |||
| int | ioret | |||
| ) |
Notify layers about transfer completion.
Invoked by transfer sub-system (which is a part of osc) to notify layers that a transfer, of which this page is a part of has completed.
Completion call-backs are executed in the bottom-up order, so that uppermost layer (llite), responsible for the VFS/VM interaction runs last and can release locks safely.
Called when a decision is made to throw page out of memory.
Notifies all layers about page destruction by calling cl_page_operations::cpo_delete() method top-to-bottom.
Moves page into cl_page_state::CPS_FREEING state (this is the only place where transition to this state happens).
Eliminates all venues through which new references to the page can be obtained:
Once page reaches cl_page_state::CPS_FREEING, all remaining references will drain after some time, at which point page will be recycled.
VM page is locked
Called when page is to be removed from the object, e.g., as a result of truncate.
Calls cl_page_operations::cpo_discard() top-to-bottom.
Releases page ownership.
Moves page into cl_page_state::CPS_CACHED.
Marks page up-to-date.
Call cl_page_operations::cpo_export() through all layers top-to-bottom. The layer responsible for VM interaction has to mark/clear page as up-to-date by the uptodate argument.
| void cl_page_gang_lookup | ( | const struct lu_env * | env, | |
| struct cl_object * | obj, | |||
| struct cl_io * | io, | |||
| pgoff_t | start, | |||
| pgoff_t | end, | |||
| struct cl_page_list * | queue, | |||
| int | nonblock, | |||
| int * | resched | |||
| ) |
Returns a list of pages by a given [start, end] of obj.
| resched | If not NULL, then we give up before hogging CPU for too long and set *resched = 1, in that case caller should implement a retry logic. |
| void cl_page_get | ( | struct cl_page * | page | ) |
Acquires an additional reference to a page.
This can be called only by caller already possessing a reference to page.
Checks whether page is protected by any extent lock is at least required mode.
| struct cl_page* cl_page_lookup | ( | struct cl_object_header * | hdr, | |
| pgoff_t | index | |||
| ) |
Returns a page with given index in the given object, or NULL if no page is found.
Acquires a reference on page.
Locking: called under cl_object_header::coh_page_guard spin-lock.
| int cl_page_make_ready | ( | const struct lu_env * | env, | |
| struct cl_page * | pg, | |||
| enum cl_req_type | crt | |||
| ) |
Notify layers that transfer formation engine decided to yank this page from the cache and to make it a part of a transfer.
Own a page, might be blocked.
| int cl_page_prep | ( | const struct lu_env * | env, | |
| struct cl_io * | io, | |||
| struct cl_page * | pg, | |||
| enum cl_req_type | crt | |||
| ) |
Prepares page for immediate transfer.
cl_page_operations::cpo_prep() is called top-to-bottom. Every layer either agrees to submit this page (by returning 0), or requests to omit this page (by returning -EALREADY). Layer handling interactions with the VM also has to inform VM that page is under transfer now.
Releases a reference to a page.
When last reference is released, page is returned to the cache, unless it is in cl_page_state::CPS_FREEING state, in which case it is immediately destroyed.
Releases page ownership without unlocking the page.
Moves page into cl_page_state::CPS_CACHED without releasing a lock on the underlying VM page (as VM is supposed to do this itself).
Unmaps page from user virtual memory.
Calls cl_page_operations::cpo_unmap() through all layers top-to-bottom. The layer responsible for VM interaction has to unmap page from user space virtual memory.