Author: kib
Date: Wed Mar 27 11:34:27 2013
New Revision: 248792
URL: http://svnweb.freebsd.org/changeset/base/248792

Log:
  Add dev_strategy_csw() function, which is similar to dev_strategy()
  but assumes that a thread reference was already obtained on the passed
  device.  Use the function from physio(), to avoid two extra dev_mtx
  lock and unlock.  Note that physio() is always used as the cdevsw
  method, or is called from a cdevsw method, and the caller already owns
  the reference.
  
  dev_strategy() is left to keep KPI intact, but now it is implemented
  as a wrapper around dev_strategy_csw().
  
  Do some style cleanup in physio().
  
  Requested and reviewed by:    kan (previous version)
  Sponsored by: The FreeBSD Foundation
  MFC after:    2 weeks

Modified:
  head/sys/kern/kern_physio.c
  head/sys/kern/vfs_bio.c
  head/sys/sys/conf.h

Modified: head/sys/kern/kern_physio.c
==============================================================================
--- head/sys/kern/kern_physio.c Wed Mar 27 11:31:39 2013        (r248791)
+++ head/sys/kern/kern_physio.c Wed Mar 27 11:34:27 2013        (r248792)
@@ -34,11 +34,11 @@ __FBSDID("$FreeBSD$");
 int
 physio(struct cdev *dev, struct uio *uio, int ioflag)
 {
-       int i;
-       int error;
+       struct buf *bp;
+       struct cdevsw *csw;
        caddr_t sa;
        u_int iolen;
-       struct buf *bp;
+       int error, i, mapped;
 
        /* Keep the process UPAGES from being swapped. XXX: why ? */
        PHOLD(curproc);
@@ -91,11 +91,8 @@ physio(struct cdev *dev, struct uio *uio
 
                        bp->b_blkno = btodb(bp->b_offset);
 
+                       csw = dev->si_devsw;
                        if (uio->uio_segflg == UIO_USERSPACE) {
-                               struct cdevsw *csw;
-                               int mapped;
-
-                               csw = dev->si_devsw;
                                if (csw != NULL &&
                                     (csw->d_flags & D_UNMAPPED_IO) != 0)
                                        mapped = 0;
@@ -107,7 +104,7 @@ physio(struct cdev *dev, struct uio *uio
                                }
                        }
 
-                       dev_strategy(dev, bp);
+                       dev_strategy_csw(dev, csw, bp);
                        if (uio->uio_rw == UIO_READ)
                                bwait(bp, PRIBIO, "physrd");
                        else

Modified: head/sys/kern/vfs_bio.c
==============================================================================
--- head/sys/kern/vfs_bio.c     Wed Mar 27 11:31:39 2013        (r248791)
+++ head/sys/kern/vfs_bio.c     Wed Mar 27 11:34:27 2013        (r248792)
@@ -3687,11 +3687,34 @@ void
 dev_strategy(struct cdev *dev, struct buf *bp)
 {
        struct cdevsw *csw;
-       struct bio *bip;
        int ref;
 
-       if ((!bp->b_iocmd) || (bp->b_iocmd & (bp->b_iocmd - 1)))
-               panic("b_iocmd botch");
+       KASSERT(dev->si_refcount > 0,
+           ("dev_strategy on un-referenced struct cdev *(%s) %p",
+           devtoname(dev), dev));
+
+       csw = dev_refthread(dev, &ref);
+       dev_strategy_csw(dev, csw, bp);
+       dev_relthread(dev, ref);
+}
+
+void
+dev_strategy_csw(struct cdev *dev, struct cdevsw *csw, struct buf *bp)
+{
+       struct bio *bip;
+
+       KASSERT(bp->b_iocmd == BIO_READ || bp->b_iocmd == BIO_WRITE,
+           ("b_iocmd botch"));
+       KASSERT(((dev->si_flags & SI_ETERNAL) != 0 && csw != NULL) ||
+           dev->si_threadcount > 0,
+           ("dev_strategy_csw threadcount cdev *(%s) %p", devtoname(dev),
+           dev));
+       if (csw == NULL) {
+               bp->b_error = ENXIO;
+               bp->b_ioflags = BIO_ERROR;
+               bufdone(bp);
+               return;
+       }
        for (;;) {
                bip = g_new_bio();
                if (bip != NULL)
@@ -3707,19 +3730,7 @@ dev_strategy(struct cdev *dev, struct bu
        bip->bio_done = bufdonebio;
        bip->bio_caller2 = bp;
        bip->bio_dev = dev;
-       KASSERT(dev->si_refcount > 0,
-           ("dev_strategy on un-referenced struct cdev *(%s)",
-           devtoname(dev)));
-       csw = dev_refthread(dev, &ref);
-       if (csw == NULL) {
-               g_destroy_bio(bip);
-               bp->b_error = ENXIO;
-               bp->b_ioflags = BIO_ERROR;
-               bufdone(bp);
-               return;
-       }
        (*csw->d_strategy)(bip);
-       dev_relthread(dev, ref);
 }
 
 /*

Modified: head/sys/sys/conf.h
==============================================================================
--- head/sys/sys/conf.h Wed Mar 27 11:31:39 2013        (r248791)
+++ head/sys/sys/conf.h Wed Mar 27 11:34:27 2013        (r248792)
@@ -255,6 +255,7 @@ void        dev_ref(struct cdev *dev);
 void   dev_refl(struct cdev *dev);
 void   dev_rel(struct cdev *dev);
 void   dev_strategy(struct cdev *dev, struct buf *bp);
+void   dev_strategy_csw(struct cdev *dev, struct cdevsw *csw, struct buf *bp);
 struct cdev *make_dev(struct cdevsw *_devsw, int _unit, uid_t _uid, gid_t _gid,
                int _perms, const char *_fmt, ...) __printflike(6, 7);
 struct cdev *make_dev_cred(struct cdevsw *_devsw, int _unit,
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to