From: Douglas Gilbert <dougg@torque.net>
To: Kai Makisara <Kai.Makisara@kolumbus.fi>
Cc: linux-scsi@vger.kernel.org, ingo.oeser@informatik.tu-chemnitz.de
Subject: Re: [RFC][PATCH] Direct I/O for the SCSI tapes
Date: Sun, 28 Jul 2002 00:39:44 -0400 [thread overview]
Message-ID: <3D437590.8D69B132@torque.net> (raw)
In-Reply-To: Pine.LNX.4.44.0207271530500.1090-100000@kai.makisara.local
Kai Makisara wrote:
>
> The URL http://www.kolumbus.fi/kai.makisara/st-dio.html contains
> explanation and a link to a patch implementing direct I/O in the SCSI tape
> driver (st). Before adding this to the official kernel, I would like to
> get some feedback on this patch. If no one is interested in this
> enhancement and/or it seems to be useless, it will probably be left to
> collect dust.
Kai,
Faster throughput and less CPU overhead seem pretty good reasons
to use direct IO. With larger disk sizes, faster tape transfer speeds
are needed to backup them up in a reasonable time. So I hope your
patch doesn't collect dust. Also most high speed application that
use sg are _streaming_ to disks [I have one report of > 320 MB/sec].
Perhaps people may one day use a purpose built command set for
streaming like SSC rather than SBC (as used by direct access devices).
It was interesting to see that your patch used variants of Ingo Oeser's
sg_map_user_pages() [see Kai's version shown below] **. My interest in
those functions is that I would like to use them in sg (since kiobufs
have been removed from lk 2.5). According to Ingo several other char
drivers that previously used kiobufs are probably looking for
replacements as well.
Since they are general routines of use to char drivers that
build scatter gather lists (block drivers have bio) perhaps they
should be placed in some common area.
Doug Gilbert
** lkml 2002-07-19 22:39:18 Ingo Oeser "Re: [never mind] kiobufs and highmem"
Kai's st_map_user_pages() and st_unmap_user_pages() follow:
vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
static int st_map_user_pages(struct scatterlist *sgl, const unsigned int max_pages,
unsigned long uaddr, size_t count, int rw,
unsigned long max_pfn)
{
int res, i, j;
unsigned int nr_pages;
struct page **pages;
nr_pages = ((uaddr & ~PAGE_MASK) + count - 1 + ~PAGE_MASK) >> PAGE_SHIFT;
/* User attempted Overflow! */
if ((uaddr + count) < uaddr)
return -EINVAL;
/* Too big */
if (nr_pages > max_pages)
return -ENOMEM;
/* Hmm? */
if (count == 0)
return 0;
if ((pages = kmalloc(max_pages * sizeof(*pages), GFP_ATOMIC)) == NULL)
return -ENOMEM;
/* Try to fault in all of the necessary pages */
down_read(¤t->mm->mmap_sem);
/* rw==READ means read from drive, write into memory area */
res = get_user_pages(
current,
current->mm,
uaddr,
nr_pages,
rw == READ,
0, /* don't force */
pages,
NULL);
up_read(¤t->mm->mmap_sem);
/* Errors and no page mapped should return here */
if (res < nr_pages)
goto out_unmap;
for (i=0; i < nr_pages; i++) {
/* FIXME: flush superflous for rw==READ,
* probably wrong function for rw==WRITE
*/
flush_dcache_page(pages[i]);
if (page_to_pfn(pages[i]) > max_pfn)
goto out_unlock;
/* ?? Is locking needed? I don't think so */
/* if (TestSetPageLocked(pages[i]))
goto out_unlock; */
}
/* Populate the scatter/gather list */
sgl[0].page = pages[0];
sgl[0].offset = uaddr & ~PAGE_MASK;
if (nr_pages > 1) {
sgl[0].length = PAGE_SIZE - sgl[0].offset;
count -= sgl[0].length;
for (i=1; i < nr_pages ; i++) {
sgl[i].offset = 0;
sgl[i].page = pages[i];
sgl[i].length = count < PAGE_SIZE ? count : PAGE_SIZE;
count -= PAGE_SIZE;
}
}
else {
sgl[0].length = count;
}
kfree(pages);
return nr_pages;
out_unlock:
/* for (j=0; j < i; j++)
unlock_page(pages[j]); */
res = 0;
out_unmap:
if (res > 0)
for (j=0; j < res; j++)
page_cache_release(pages[j]);
kfree(pages);
return res;
}
/* And unmap them... */
static int st_unmap_user_pages(struct scatterlist *sgl, const unsigned int nr_pages,
int dirtied)
{
int i;
for (i=0; i < nr_pages; i++) {
if (dirtied && !PageReserved(sgl[i].page))
SetPageDirty(sgl[i].page);
/* unlock_page(sgl[i].page); */
/* FIXME: cache flush missing for rw==READ
* FIXME: call the correct reference counting function
*/
page_cache_release(sgl[i].page);
}
return 0;
}
next prev parent reply other threads:[~2002-07-28 4:39 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2002-07-27 12:38 [RFC][PATCH] Direct I/O for the SCSI tapes Kai Makisara
2002-07-28 4:39 ` Douglas Gilbert [this message]
2002-07-28 11:03 ` Kai Makisara
2002-07-28 22:59 ` Ingo Oeser
2002-07-29 18:45 ` Kai Makisara
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=3D437590.8D69B132@torque.net \
--to=dougg@torque.net \
--cc=Kai.Makisara@kolumbus.fi \
--cc=ingo.oeser@informatik.tu-chemnitz.de \
--cc=linux-scsi@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.