mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Ingo Oeser <ingo.oeser@informatik.tu-chemnitz.de>
To: William D Waddington <csbwaddington@att.net>
Cc: linux-kernel@vger.kernel.org
Subject: Re: [never mind] kiobufs and highmem
Date: Sat, 20 Jul 2002 00:39:18 +0200	[thread overview]
Message-ID: <20020720003918.G758@nightmaster.csn.tu-chemnitz.de> (raw)
In-Reply-To: <ic9gju44p7ukriuv4etl0tdc5f6uf5s08m@4ax.com>; from csbwaddington@att.net on Fri, Jul 19, 2002 at 08:00:00AM -0700

On Fri, Jul 19, 2002 at 08:00:00AM -0700, William D Waddington wrote:
> I haven't yet figured out how to allocate a (possibly) non-contiguous
> buffer, since vmalloc is frowned on, or how to populate the kiobuf
> with its pages.

Don't use the kiobuf, since it is bloated.

Try this instead:


/* Pin down user pages and put them into a scatter gather list */
int sg_map_user_pages(struct scatterlist *sgl, const unsigned int max_pages, 
		unsigned long uaddr, size_t count, int rw) {
	int res, i;
	unsigned int nr_pages=((uaddr & ~PAGE_MASK) + count - 1 + ~PAGE_MASK) >> PAGE_SHIFT;
	struct page *pages[max_pages];

	/* User attempted Overflow! */
	if ((uaddr + count) < uaddr)
		return -EINVAL;

	/* To big */
	if (nr_pages > max_pages)
		return -ENOMEM;

	/* Hmm? */
	if (count == 0)
		return 0;

	/* Not enough SGL entries provided! */
	BUG_ON((((uaddr & ~PAGE_MASK) + count + ~PAGE_MASK) >> PAGE_SHIFT) > max_pages );

	down_read(&current->mm->mmap_sem);
	res = get_user_pages(
			current,
			current->mm,
			uaddr,
			nr_pages,
			rw == READ, /* logic is perversed^Wreversed here :-( */
			0, /* don't force */
			&pages[0],
			NULL);
	up_read(&current->mm->mmap_sem);

	/* Errors and no page mapped should return here */
	if (res <= 0) return res;

	memset(sgl, 0, sizeof(*sgl) * nr_pages);

	sgl[0].page = pages[0];	
	sgl[0].offset = uaddr & PAGE_MASK;
	
	/* Page crossing transfers need these adjustments */
	if (res > 1) {
		for (i=1; i < res ; i++) {
			sgl[i].offset = 0;
			sgl[i].page = pages[i];	
			sgl[i].length = PAGE_SIZE;
		}
		sgl[0].length = PAGE_SIZE - sgl[0].offset;
		count -= sgl[0].length;
		count -= (res - 2) * PAGE_SIZE;
	}

	sgl[res - 1].length = count;

	return res;
}

/* And unmap them... */
int sg_unmap_user_pages(struct scatterlist *sgl, const unsigned int nr_pages) {
	int i;

	for (i=0; i < nr_pages; i++)
		page_cache_release(sgl[i].page);

	return 0;
}


That will give you nearly the same. You just have to lock_page()
the pages and UnlockPage() yourself.

Don't give to high values for max_pages, because this might
overflow your stack.

Do the pci_map_sg() after sg_map_user_pages() and pci_unmap_sg()
before sg_unmap_user_pages().

This should work. If you have highmem pages and your device can't
handle >32-bit physical addresses, then kmap() them
before pci_map_sg()ing them and kunmap() them after
pci_unmap_sg()ing.

kiobufs are (next to) useless for character io devices.

Hope that helps

Regards

Ingo Oeser
-- 
Science is what we can tell a computer. Art is everything else. --- D.E.Knuth

  parent reply	other threads:[~2002-07-19 22:46 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2002-07-19 15:00 William D Waddington
2002-07-19 15:32 ` Benjamin LaHaise
2002-07-19 22:39 ` Ingo Oeser [this message]
2002-07-23 11:17   ` Gerd Knorr

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20020720003918.G758@nightmaster.csn.tu-chemnitz.de \
    --to=ingo.oeser@informatik.tu-chemnitz.de \
    --cc=csbwaddington@att.net \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®