linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* locking down memory and map_user_kiobuf
@ 2003-06-16 19:51 Lee, Shuyu
  0 siblings, 0 replies; only message in thread
From: Lee, Shuyu @ 2003-06-16 19:51 UTC (permalink / raw)
  To: Linux Kernel Mailing List

Hi, all.

I am developing a Linux driver which allows the hardware to DMA image data
directly into an image buffer allocated by a user. Everything appears to be
working in my driver test, until the full application is run. After some
investigation, it seems that my code which should lock down the image buffer
does not really work. When the memory usage is up, the image buffer is paged
out, causing segmentation fault. If I force all pages to be resident by
writing one byte to every page of the image buffer right before I call
map_user_kiobuf(), it seems to work. By the way, I am using RedHat 8.0
(2.4.18-14) and gcc 3.2 that comes with RedHat 8.0

Here is the code that I use to lock down the image buffer allocated by user
and passed to the driver by an ioctl call:
retVal = alloc_kiovec(1, &pDMAField->iobuf);
// Test code: write to one byte of every page of the image buffer here
retVal = map_user_kiobuf(READ, pDMAField->iobuf, (ULONG)pImgVirt, 
                         pDMAField->height * pDMAField->pitch);

My questions are:
1)	Does map_user_kiobuf() only work when the memory to be locked down
is resident? 
2)	Do I need to call lock_kiovec() as well?
3)	I have tried with both "READ" and "WRITE" when calling
map_user_kiobuf(), does it make any difference?
4)	I took a look at map_user_kiobuf() implementation in memory.c
(attached below). It seems that all it does is to force all pages of the
buffer to be paged in, and then to flush the cache. Am I missing anything?

Any help and suggestion would be greatly appreciated.
Shuyu

// From RedHat 8.0: /usr/src/linux-2.4.18-14/mm/memory.c
int map_user_kiobuf(int rw, struct kiobuf *iobuf, unsigned long va, size_t
len)
{
	int pgcount, err;
	struct mm_struct *	mm;
	
	/* Make sure the iobuf is not already mapped somewhere. */
	if (iobuf->nr_pages)
		return -EINVAL;

	mm = current->mm;
	dprintk ("map_user_kiobuf: begin\n");
	
	pgcount = (va + len + PAGE_SIZE - 1)/PAGE_SIZE - va/PAGE_SIZE;
	/* mapping 0 bytes is not permitted */
	if (!pgcount) BUG();
	err = expand_kiobuf(iobuf, pgcount);
	if (err)
		return err;

	iobuf->locked = 0;
	iobuf->offset = va & (PAGE_SIZE-1);
	iobuf->length = len;
	
	/* Try to fault in all of the necessary pages */
	down_read(&mm->mmap_sem);
	/* rw==READ means read from disk, write into memory area */
	err = get_user_pages(current, mm, va, pgcount,
			(rw==READ), 0, iobuf->maplist, NULL);
	up_read(&mm->mmap_sem);
	if (err < 0) {
		unmap_kiobuf(iobuf);
		dprintk ("map_user_kiobuf: end %d\n", err);
		return err;
	}
	iobuf->nr_pages = err;
	while (pgcount--) {
		/* FIXME: flush superflous for rw==READ,
		 * probably wrong function for rw==WRITE
		 */
		flush_dcache_page(iobuf->maplist[pgcount]);
	}
	dprintk ("map_user_kiobuf: end OK\n");
	return 0;
}






^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2003-06-16 19:38 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-06-16 19:51 locking down memory and map_user_kiobuf Lee, Shuyu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).