* raw access and qlogic isp device driver?
@ 2001-03-23 16:33 Joel Gallun
2001-03-23 16:45 ` Alan Cox
0 siblings, 1 reply; 6+ messages in thread
From: Joel Gallun @ 2001-03-23 16:33 UTC (permalink / raw)
To: linux-kernel
I'm trying to use Stephen Tweedie's raw device support to access disks
attached to a Qlogic ISP 1040/B controller and kernel oopses.
Has anyone used the raw device with qlogicisp driver? Does anyone have any
interest in looking at this?
Thanks!
--
Joel Gallun joel@tux.org
Open system and Internet consulting http://www.tux.org/~joel
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: raw access and qlogic isp device driver?
2001-03-23 16:33 raw access and qlogic isp device driver? Joel Gallun
@ 2001-03-23 16:45 ` Alan Cox
2001-03-23 19:25 ` Mark Mitchell
2001-03-23 20:09 ` raw access and qlogic isp device driver? Joel Gallun
0 siblings, 2 replies; 6+ messages in thread
From: Alan Cox @ 2001-03-23 16:45 UTC (permalink / raw)
To: Joel Gallun; +Cc: linux-kernel
> I'm trying to use Stephen Tweedie's raw device support to access disks
> attached to a Qlogic ISP 1040/B controller and kernel oopses.
2.2 or 2.4 ?
> Has anyone used the raw device with qlogicisp driver? Does anyone have any
> interest in looking at this?
It shouldnt matter which driver is involved, but 2.4 raw stuff is reported
broken still
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: raw access and qlogic isp device driver?
2001-03-23 16:45 ` Alan Cox
@ 2001-03-23 19:25 ` Mark Mitchell
2001-03-23 22:13 ` Alan Cox
2001-03-23 20:09 ` raw access and qlogic isp device driver? Joel Gallun
1 sibling, 1 reply; 6+ messages in thread
From: Mark Mitchell @ 2001-03-23 19:25 UTC (permalink / raw)
To: linux-kernel
Alan Cox wrote:
>
> ...
>
> > Has anyone used the raw device with qlogicisp driver? Does
> > anyone have any interest in looking at this?
>
> It shouldnt matter which driver is involved, but 2.4 raw stuff
> is reported broken still
Any chance of anyone elaborating on any RAWIO flaws?
*Seems* to work fine with:
- 2.4.2 (inc Dave Miller's zero copy patch)
- qlogic fc driver & qla2200
- PIII
- Seagate ST39103fc drives in a JBOD
I really need to know any *specific* issues with RAWIO.
Cheers,
Mark.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: raw access and qlogic isp device driver?
2001-03-23 16:45 ` Alan Cox
2001-03-23 19:25 ` Mark Mitchell
@ 2001-03-23 20:09 ` Joel Gallun
1 sibling, 0 replies; 6+ messages in thread
From: Joel Gallun @ 2001-03-23 20:09 UTC (permalink / raw)
To: Alan Cox; +Cc: linux-kernel
On Fri, 23 Mar 2001, Alan Cox wrote:
> > I'm trying to use Stephen Tweedie's raw device support to access disks
> > attached to a Qlogic ISP 1040/B controller and kernel oopses.
>
> 2.2 or 2.4 ?
2.4.2
> > Has anyone used the raw device with qlogicisp driver? Does anyone have any
> > interest in looking at this?
>
> It shouldnt matter which driver is involved, but 2.4 raw stuff is reported
> broken still
We've used raw with the compaq smart2 and symbios 53c8xx drivers without
problems on 2.4.2, but shortly after we touch a raw device over top of the
qlogicisp we get an oops.
Joel
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: raw access and qlogic isp device driver?
2001-03-23 19:25 ` Mark Mitchell
@ 2001-03-23 22:13 ` Alan Cox
2001-03-28 4:49 ` [PATCH-2.4.2ac26] fix raw IO Stephen Tweedie
0 siblings, 1 reply; 6+ messages in thread
From: Alan Cox @ 2001-03-23 22:13 UTC (permalink / raw)
To: Mark Mitchell; +Cc: linux-kernel
> Any chance of anyone elaborating on any RAWIO flaws?
>
> *Seems* to work fine with:
> - 2.4.2 (inc Dave Miller's zero copy patch)
> - qlogic fc driver & qla2200
> - PIII
> - Seagate ST39103fc drives in a JBOD
>
> I really need to know any *specific* issues with RAWIO.
All I know is that Stephen said he had a set of patches needed to fix rawio.
I've not applied them nor afaik has Linus.
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH-2.4.2ac26] fix raw IO
2001-03-23 22:13 ` Alan Cox
@ 2001-03-28 4:49 ` Stephen Tweedie
0 siblings, 0 replies; 6+ messages in thread
From: Stephen Tweedie @ 2001-03-28 4:49 UTC (permalink / raw)
To: Alan Cox, Linus Torvalds
Cc: Mark Mitchell, linux-kernel, Stephen Tweedie, Andrea Arcangeli,
Ben LaHaise, linux-mm, Helge Deller, Steve Lord
[-- Attachment #1: Type: text/plain, Size: 890 bytes --]
Hi,
On Fri, Mar 23, 2001 at 10:13:44PM +0000, Alan Cox wrote:
> >
> > I really need to know any *specific* issues with RAWIO.
>
> All I know is that Stephen said he had a set of patches needed to fix rawio.
> I've not applied them nor afaik has Linus.
Ben LaHaise has been testing Oracle on raw IO with the new patches,
and I only got the thumbs up on that yesterday. Patch below.
This fixes:
Fix two problems when faulting in pages for direct access:
Check pmd and pgd entries for validity in follow page;
Be prepared to call handle_mm_fault more than once if necessary
to complete the page fault.
Allow raw devices to be unbound by binding to dev (0,0)
Use SetPageDirty to mark pages dirty in memory after a read from disk
Wait for pending IO correctly if an error occurs during IO
Return -EIO if an IO error occurs in the first block of the IO
Cheers,
Stephen
[-- Attachment #2: 2.4.2-ac26.raw-fixes.patch --]
[-- Type: text/plain, Size: 6856 bytes --]
--- linux-2.4.2-ac26/drivers/char/raw.c.~1~ Tue Mar 27 18:41:07 2001
+++ linux-2.4.2-ac26/drivers/char/raw.c Wed Mar 28 03:33:16 2001
@@ -184,7 +184,8 @@
* major/minor numbers make sense.
*/
- if (rq.block_major == NODEV ||
+ if ((rq.block_major == NODEV &&
+ rq.block_minor != NODEV) ||
rq.block_major > MAX_BLKDEV ||
rq.block_minor > MINORMASK) {
err = -EINVAL;
@@ -313,24 +314,21 @@
err = map_user_kiobuf(rw, iobuf, (unsigned long) buf, iosize);
if (err)
break;
-#if 0
- err = lock_kiovec(1, &iobuf, 1);
- if (err)
- break;
-#endif
-
+
for (i=0; i < blocks; i++)
b[i] = blocknr++;
err = brw_kiovec(rw, 1, &iobuf, dev, b, sector_size);
-
+ if (rw == READ && err > 0)
+ mark_dirty_kiobuf(iobuf, err);
+
if (err >= 0) {
transferred += err;
size -= err;
buf += err;
}
- unmap_kiobuf(iobuf); /* The unlock_kiobuf is implicit here */
+ unmap_kiobuf(iobuf);
if (err != iosize)
break;
--- linux-2.4.2-ac26/fs/buffer.c.~1~ Tue Mar 27 18:41:40 2001
+++ linux-2.4.2-ac26/fs/buffer.c Wed Mar 28 03:33:16 2001
@@ -2016,12 +2016,12 @@
static int wait_kio(int rw, int nr, struct buffer_head *bh[], int size)
{
- int iosize;
+ int iosize, err;
int i;
struct buffer_head *tmp;
-
iosize = 0;
+ err = 0;
spin_lock(&unused_list_lock);
for (i = nr; --i >= 0; ) {
@@ -2038,13 +2038,16 @@
clearing iosize on error calculates the
amount of IO before the first error. */
iosize = 0;
+ err = -EIO;
}
__put_unused_buffer_head(tmp);
}
spin_unlock(&unused_list_lock);
- return iosize;
+ if (iosize)
+ return iosize;
+ return err;
}
/*
@@ -2157,29 +2160,22 @@
} /* End of page loop */
} /* End of iovec loop */
+ error:
/* Is there any IO still left to submit? */
if (bhind) {
- err = wait_kio(rw, bhind, bh, size);
- if (err >= 0)
- transferred += err;
+ int tmp_err;
+ tmp_err = wait_kio(rw, bhind, bh, size);
+ if (tmp_err >= 0)
+ transferred += tmp_err;
else
- goto finished;
+ if (!err)
+ err = tmp_err;
}
finished:
if (transferred)
return transferred;
return err;
-
- error:
- /* We got an error allocating the bh'es. Just free the current
- buffer_heads and exit. */
- spin_lock(&unused_list_lock);
- for (i = bhind; --i >= 0; ) {
- __put_unused_buffer_head(bh[i]);
- }
- spin_unlock(&unused_list_lock);
- goto finished;
}
/*
--- linux-2.4.2-ac26/include/linux/iobuf.h.~1~ Thu Feb 22 00:10:12 2001
+++ linux-2.4.2-ac26/include/linux/iobuf.h Wed Mar 28 03:33:16 2001
@@ -64,6 +64,7 @@
void unmap_kiobuf(struct kiobuf *iobuf);
int lock_kiovec(int nr, struct kiobuf *iovec[], int wait);
int unlock_kiovec(int nr, struct kiobuf *iovec[]);
+void mark_dirty_kiobuf(struct kiobuf *iobuf, int bytes);
/* fs/iobuf.c */
--- linux-2.4.2-ac26/mm/memory.c.~1~ Tue Mar 27 18:41:50 2001
+++ linux-2.4.2-ac26/mm/memory.c Wed Mar 28 03:36:42 2001
@@ -382,20 +382,33 @@
/*
* Do a quick page-table lookup for a single page.
*/
-static struct page * follow_page(unsigned long address)
+static struct page * follow_page(unsigned long address, int write)
{
pgd_t *pgd;
pmd_t *pmd;
+ pte_t *ptep, pte;
pgd = pgd_offset(current->mm, address);
+ if (pgd_none(*pgd) || pgd_bad(*pgd))
+ goto out;
+
pmd = pmd_offset(pgd, address);
- if (pmd) {
- pte_t * pte = pte_offset(pmd, address);
- if (pte && pte_present(*pte))
- return pte_page(*pte);
+ if (pmd_none(*pmd) || pmd_bad(*pmd))
+ goto out;
+
+ ptep = pte_offset(pmd, address);
+ if (!ptep)
+ goto out;
+
+ pte = *ptep;
+ if (pte_present(pte)) {
+ if (!write ||
+ (pte_write(pte) && pte_dirty(pte)))
+ return pte_page(pte);
}
-
- return NULL;
+
+out:
+ return 0;
}
/*
@@ -425,7 +438,7 @@
struct vm_area_struct * vma = 0;
struct page * map;
int i;
- int datain = (rw == READ);
+ int to_user = (rw == READ);
/* Make sure the iobuf is not already mapped somewhere. */
if (iobuf->nr_pages)
@@ -448,13 +461,18 @@
iobuf->length = len;
i = 0;
+
+ spin_lock(&mm->page_table_lock);
/*
* First of all, try to fault in all of the necessary pages
*/
while (ptr < end) {
if (!vma || ptr >= vma->vm_end) {
+
+ spin_unlock(&mm->page_table_lock);
vma = find_vma(current->mm, ptr);
+
if (!vma)
goto out_unlock;
if (vma->vm_start > ptr) {
@@ -463,34 +481,49 @@
if (expand_stack(vma, ptr))
goto out_unlock;
}
- if (((datain) && (!(vma->vm_flags & VM_WRITE))) ||
- (!(vma->vm_flags & VM_READ))) {
+ if (((to_user) && (!(vma->vm_flags & VM_WRITE))) ||
+ (!(vma->vm_flags & VM_READ))) {
err = -EACCES;
goto out_unlock;
}
+
+ spin_lock(&mm->page_table_lock);
}
- if (handle_mm_fault(current->mm, vma, ptr, datain) <= 0)
- goto out_unlock;
- spin_lock(&mm->page_table_lock);
- map = follow_page(ptr);
- if (!map) {
+ while (1) {
+ int ret;
+
+ map = follow_page(ptr, to_user);
+ if (map) {
+ map = get_page_map(map);
+ if (map) {
+ flush_dcache_page(map);
+ atomic_inc(&map->count);
+ } else
+ printk (KERN_INFO
+ "Mapped page missing [%d]\n",
+ i);
+ break;
+ }
+
spin_unlock(&mm->page_table_lock);
- dprintk (KERN_ERR "Missing page in map_user_kiobuf\n");
- goto out_unlock;
+
+ ret = handle_mm_fault(current->mm, vma, ptr, to_user);
+ if (ret <= 0) {
+ if (ret)
+ err = -ENOMEM;
+ goto out_unlock;
+ }
+
+ spin_lock(&mm->page_table_lock);
}
- map = get_page_map(map);
- if (map) {
- flush_dcache_page(map);
- atomic_inc(&map->count);
- } else
- printk (KERN_INFO "Mapped page missing [%d]\n", i);
- spin_unlock(&mm->page_table_lock);
+
iobuf->maplist[i] = map;
iobuf->nr_pages = ++i;
ptr += PAGE_SIZE;
}
+ spin_unlock(&mm->page_table_lock);
up_write(&mm->mmap_sem);
dprintk ("map_user_kiobuf: end OK\n");
return 0;
@@ -524,6 +557,39 @@
iobuf->nr_pages = 0;
iobuf->locked = 0;
+}
+
+
+/*
+ * Mark all of the pages in a kiobuf as dirty
+ *
+ * We need to be able to deal with short reads from disk: if an IO error
+ * occurs, the number of bytes read into memory may be less than the
+ * size of the kiobuf, so we have to stop marking pages dirty once the
+ * requested byte count has been reached.
+ */
+
+void mark_dirty_kiobuf(struct kiobuf *iobuf, int bytes)
+{
+ int index, offset, remaining;
+ struct page *page;
+
+ index = iobuf->offset >> PAGE_SHIFT;
+ offset = iobuf->offset & ~PAGE_MASK;
+ remaining = bytes;
+ if (remaining > iobuf->length)
+ remaining = iobuf->length;
+
+ while (remaining > 0 && index < iobuf->nr_pages) {
+ page = iobuf->maplist[index];
+
+ if (!PageReserved(page))
+ SetPageDirty(page);
+
+ remaining -= (PAGE_SIZE - offset);
+ offset = 0;
+ index++;
+ }
}
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2001-03-28 4:53 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2001-03-23 16:33 raw access and qlogic isp device driver? Joel Gallun
2001-03-23 16:45 ` Alan Cox
2001-03-23 19:25 ` Mark Mitchell
2001-03-23 22:13 ` Alan Cox
2001-03-28 4:49 ` [PATCH-2.4.2ac26] fix raw IO Stephen Tweedie
2001-03-23 20:09 ` raw access and qlogic isp device driver? Joel Gallun
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox