public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* 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