Re: Equivalent of Linux kmap on Mac OS
Re: Equivalent of Linux kmap on Mac OS
- Subject: Re: Equivalent of Linux kmap on Mac OS
- From: Anton Altaparmakov <email@hidden>
- Date: Wed, 7 Mar 2007 14:01:18 +0000
On 7 Mar 2007, at 12:37, Terry Lambert wrote:
On Mar 7, 2007, at 3:45 AM, Anton Altaparmakov wrote:
[ ... ]
/* Create a page list for the wanted page. */
kerr = ubc_create_upl(ni->vn, ofs, PAGE_SIZE, upl, pl,
UPL_SET_LITE |
(rw ? UPL_WILL_MODIFY : 0));
if (kerr != KERN_SUCCESS)
panic("%s(): Failed to get page (error %d).\n",
__FUNCTION__,
(int)kerr);
/*
* If the page is not valid, need to read it in from the
vnode now thus
* making it valid.
*/
if (!upl_valid_page(*pl, 0)) {
ntfs_debug("Reading page as it was not valid.");
err = ntfs_pagein(ni, ofs, PAGE_SIZE, *upl, 0,
UPL_IOSYNC | UPL_NOCOMMIT);
if (err) {
ntfs_error(ni->vol->mp, "Failed to read
page (error "
"%d).", err);
goto pagein_err;
}
}
/* Map the page into the kernel's address space. */
kerr = ubc_upl_map(*upl, (vm_offset_t*)kaddr);
if (kerr == KERN_SUCCESS) {
ntfs_debug("Done.");
return 0;
}
ntfs_error(ni->vol->mp, "Failed to map page (error %d).",
(int)kerr);
err = EIO;
I may be misunderstanding the simplification you performed, and if
so, forgive me...
You want to call ubc_upl_map() before you do the I/O, or the UPL
could have been recycled while the system was under extreme
pressure, which would result in it being thrown away before a
mapping was established to hold it in place. It looks like the
failure mode in this case would cause a ""Failed to map page"
message if debugging was on, and an EIO, which I suspect would not
be re-driven down.
Um, surely once the ubc_create_upl() call succeeds I have total and
exclusive control of the UPL and _nothing_ can happen to it at all
unless I do it myself for as long as I have not released the UPL back
to the VM.
Any processes that try to do anything with the pages in my UPL will
block because UPLs provide exclusive access to the pages until I
either abort or commit the UPL.
The ubc_upl_map() only provides a mapping of the pages into a
contiguous virtual memory "segment" (or maybe better called "region"
to avoid confusion with a CPU segment...). It does not do anything
else.
If what you say were to be correct the cluster i/o layer would not
actually work as that works with the UPLs without mapping the pages
for the majority of the time (ubc_upl_map() is very heavy weight and
has to be avoided if/where possible). For example see bsd/vfs/
vfs_cluster.c::cluster_zero() which operates directly on the
underlying physical memory without ever mapping it into kernel
virtual address space as well as bsd/vfs/
vfs_cluster.c::cluster_copy_upl_data() which does uiomove64()
directly on the physical memory.
Even if the EIO caused to to be redriven down instead of returning
an error up the stack, potentially to the program on the other end
of a system call, you might still not be very happy, if the system
stays under pressure, since it can happen repeatedly, if the load
is sustained. You probably want to look to bsd/vfs/vfs_bio.c and
how HFS does things for your example (e.g. the usage of ubc_upl_map
() in buf_map() & company).
You probably also want to drive the I/O through the fault on
access, through the page-in path, rather than an explicit I/O
through ntfs_pagein(). The reason the cd9660 code does it the
other way is because CD's don't have normal page-aligned block
boundaries, so avoiding the direct I/O and letting the VM system
schedule instead could be inefficient.
I do not think that is possible / would work at all as no page fault
would be triggered once you have created the UPL. The page is yours
and yours alone at that point nothing including the kernel itself can
touch it or do anything at all to it.
Best regards,
Anton
--
Anton Altaparmakov <aia21 at cam.ac.uk> (replace at with @)
Unix Support, Computing Service, University of Cambridge, CB2 3QH, UK
Linux NTFS maintainer, http://www.linux-ntfs.org/
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-kernel mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden