Kirk McKusick wrote:
[..]

I've been tinkering around for a while and think I have at least a
partial fix for the remaining problems.

Certain places use B_CALL and have biodone() from the b_iodone routine,
so we can't reliably use B_ASYNC as an indicator of needing to reassign
to LK_KERNPROC.  We have to do it on a case-by-case basis.

It's easier to do cluster_head processing at the point it's gathered
rather than in BUF_KERNPROC().

vfs_cluster.c is confusing, but I think I've figured out how to get it
right. I'm not 100% sure about checking for B_CALL in both cases prior
to VOP_STRATEGY(), and maybe reqbp needs to be considered for the first
read in cluster_read().

Also, I think the inline BUF_*() routines/macros would be better as
routines in something like vfs_bio.c as the internals cause problems
with prototypes etc.

I think this patch fixes the remaining panics in pageouts and clustering.

Index: kern/vfs_bio.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/vfs_bio.c,v
retrieving revision 1.218
diff -u -r1.218 vfs_bio.c
--- vfs_bio.c   1999/06/28 15:32:10     1.218
+++ vfs_bio.c   1999/06/28 16:48:53
@@ -517,7 +517,8 @@
        if (curproc != NULL)
                curproc->p_stats->p_ru.ru_oublock++;
        splx(s);
-       BUF_KERNPROC(bp);
+       if (oldflags & B_ASYNC)
+               BUF_KERNPROC(bp);
        VOP_STRATEGY(bp->b_vp, bp);
 
        /*
Index: kern/vfs_cluster.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/vfs_cluster.c,v
retrieving revision 1.84
diff -u -r1.84 vfs_cluster.c
--- vfs_cluster.c       1999/06/26 02:46:08     1.84
+++ vfs_cluster.c       1999/06/28 16:48:53
@@ -252,7 +252,8 @@
                if ((bp->b_flags & B_CLUSTER) == 0)
                        vfs_busy_pages(bp, 0);
                bp->b_flags &= ~(B_ERROR|B_INVAL);
-               BUF_KERNPROC(bp);
+               if (bp->b_flags & (B_ASYNC|B_CALL))
+                       BUF_KERNPROC(bp);
                error = VOP_STRATEGY(vp, bp);
                curproc->p_stats->p_ru.ru_inblock++;
        }
@@ -286,7 +287,8 @@
                        if ((rbp->b_flags & B_CLUSTER) == 0)
                                vfs_busy_pages(rbp, 0);
                        rbp->b_flags &= ~(B_ERROR|B_INVAL);
-                       BUF_KERNPROC(rbp);
+                       if (rbp->b_flags & (B_ASYNC|B_CALL))
+                               BUF_KERNPROC(rbp);
                        (void) VOP_STRATEGY(vp, rbp);
                        curproc->p_stats->p_ru.ru_inblock++;
                }
@@ -414,6 +416,11 @@
                                break;
                        }
                }
+               /*
+                * XXX fbp from caller may not be B_ASYNC, but we are going
+                * to biodone() it in cluster_callback() anyway
+                */
+               BUF_KERNPROC(tbp);
                TAILQ_INSERT_TAIL(&bp->b_cluster.cluster_head,
                        tbp, b_cluster.cluster_entry);
                for (j = 0; j < tbp->b_npages; j += 1) {
@@ -788,6 +795,7 @@
                        reassignbuf(tbp, tbp->b_vp);    /* put on clean list */
                        ++tbp->b_vp->v_numoutput;
                        splx(s);
+                       BUF_KERNPROC(tbp);
                        TAILQ_INSERT_TAIL(&bp->b_cluster.cluster_head,
                                tbp, b_cluster.cluster_entry);
                }
Index: sys/buf.h
===================================================================
RCS file: /home/ncvs/src/sys/sys/buf.h,v
retrieving revision 1.73
diff -u -r1.73 buf.h
--- buf.h       1999/06/27 11:40:03     1.73
+++ buf.h       1999/06/28 16:48:53
@@ -315,17 +315,8 @@
 static __inline void
 BUF_KERNPROC(struct buf *bp)
 {
-       struct buf *nbp;
-       int s;
 
-       s = splbio();
-       if (bp->b_flags & B_ASYNC)
-               bp->b_lock.lk_lockholder = LK_KERNPROC;
-       for (nbp = TAILQ_FIRST(&bp->b_cluster.cluster_head);
-            nbp; nbp = TAILQ_NEXT(&nbp->b_cluster, cluster_entry))
-               if (nbp->b_flags & B_ASYNC)
-                       nbp->b_lock.lk_lockholder = LK_KERNPROC;
-       splx(s);
+       bp->b_lock.lk_lockholder = LK_KERNPROC;
 }
 /*
  * Find out the number of references to a lock.


Cheers,
-Peter
--
Peter Wemm - [EMAIL PROTECTED]; [EMAIL PROTECTED]; [EMAIL PROTECTED]



To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-current" in the body of the message

Reply via email to