[BACK]Return to dk.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / dev / dkwedge

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/sys/dev/dkwedge/dk.c between version 1.91.2.1 and 1.91.2.2

version 1.91.2.1, 2016/07/20 23:47:56 version 1.91.2.2, 2017/01/07 08:56:31
Line 86  struct dkwedge_softc {
Line 86  struct dkwedge_softc {
         struct bufq_state *sc_bufq;     /* buffer queue */          struct bufq_state *sc_bufq;     /* buffer queue */
         struct callout  sc_restart_ch;  /* callout to restart I/O */          struct callout  sc_restart_ch;  /* callout to restart I/O */
   
           kmutex_t        sc_iolock;
           kcondvar_t      sc_dkdrn;
         u_int           sc_iopend;      /* I/Os pending */          u_int           sc_iopend;      /* I/Os pending */
         int             sc_flags;       /* flags (splbio) */          int             sc_flags;       /* flags (sc_iolock) */
 };  };
   
 #define DK_F_WAIT_DRAIN         0x0001  /* waiting for I/O to drain */  #define DK_F_WAIT_DRAIN         0x0001  /* waiting for I/O to drain */
Line 123  const struct bdevsw dk_bdevsw = {
Line 125  const struct bdevsw dk_bdevsw = {
         .d_dump = dkdump,          .d_dump = dkdump,
         .d_psize = dksize,          .d_psize = dksize,
         .d_discard = dkdiscard,          .d_discard = dkdiscard,
         .d_flag = D_DISK          .d_flag = D_DISK | D_MPSAFE
 };  };
   
 const struct cdevsw dk_cdevsw = {  const struct cdevsw dk_cdevsw = {
Line 138  const struct cdevsw dk_cdevsw = {
Line 140  const struct cdevsw dk_cdevsw = {
         .d_mmap = nommap,          .d_mmap = nommap,
         .d_kqfilter = nokqfilter,          .d_kqfilter = nokqfilter,
         .d_discard = dkdiscard,          .d_discard = dkdiscard,
         .d_flag = D_DISK          .d_flag = D_DISK | D_MPSAFE
 };  };
   
 static struct dkwedge_softc **dkwedges;  static struct dkwedge_softc **dkwedges;
Line 185  CFATTACH_DECL3_NEW(dk, 0,
Line 187  CFATTACH_DECL3_NEW(dk, 0,
  * dkwedge_wait_drain:   * dkwedge_wait_drain:
  *   *
  *      Wait for I/O on the wedge to drain.   *      Wait for I/O on the wedge to drain.
  *      NOTE: Must be called at splbio()!  
  */   */
 static void  static void
 dkwedge_wait_drain(struct dkwedge_softc *sc)  dkwedge_wait_drain(struct dkwedge_softc *sc)
 {  {
   
           mutex_enter(&sc->sc_iolock);
         while (sc->sc_iopend != 0) {          while (sc->sc_iopend != 0) {
                 sc->sc_flags |= DK_F_WAIT_DRAIN;                  sc->sc_flags |= DK_F_WAIT_DRAIN;
                 (void) tsleep(&sc->sc_iopend, PRIBIO, "dkdrn", 0);                  cv_wait(&sc->sc_dkdrn, &sc->sc_iolock);
         }          }
           mutex_exit(&sc->sc_iolock);
 }  }
   
 /*  /*
Line 325  dkwedge_add(struct dkwedge_info *dkw)
Line 328  dkwedge_add(struct dkwedge_info *dkw)
         callout_init(&sc->sc_restart_ch, 0);          callout_init(&sc->sc_restart_ch, 0);
         callout_setfunc(&sc->sc_restart_ch, dkrestart, sc);          callout_setfunc(&sc->sc_restart_ch, dkrestart, sc);
   
           mutex_init(&sc->sc_iolock, MUTEX_DEFAULT, IPL_BIO);
           cv_init(&sc->sc_dkdrn, "dkdrn");
   
         /*          /*
          * Wedge will be added; increment the wedge count for the parent.           * Wedge will be added; increment the wedge count for the parent.
          * Only allow this to happend if RAW_PART is the only thing open.           * Only allow this to happend if RAW_PART is the only thing open.
Line 363  dkwedge_add(struct dkwedge_info *dkw)
Line 369  dkwedge_add(struct dkwedge_info *dkw)
         }          }
         mutex_exit(&pdk->dk_openlock);          mutex_exit(&pdk->dk_openlock);
         if (error) {          if (error) {
                   cv_destroy(&sc->sc_dkdrn);
                   mutex_destroy(&sc->sc_iolock);
                 bufq_free(sc->sc_bufq);                  bufq_free(sc->sc_bufq);
                 free(sc, M_DKWEDGE);                  free(sc, M_DKWEDGE);
                 return (error);                  return (error);
Line 416  dkwedge_add(struct dkwedge_info *dkw)
Line 424  dkwedge_add(struct dkwedge_info *dkw)
                 LIST_REMOVE(sc, sc_plink);                  LIST_REMOVE(sc, sc_plink);
                 mutex_exit(&pdk->dk_openlock);                  mutex_exit(&pdk->dk_openlock);
   
                   cv_destroy(&sc->sc_dkdrn);
                   mutex_destroy(&sc->sc_iolock);
                 bufq_free(sc->sc_bufq);                  bufq_free(sc->sc_bufq);
                 free(sc, M_DKWEDGE);                  free(sc, M_DKWEDGE);
                 return (error);                  return (error);
Line 442  dkwedge_add(struct dkwedge_info *dkw)
Line 452  dkwedge_add(struct dkwedge_info *dkw)
                 LIST_REMOVE(sc, sc_plink);                  LIST_REMOVE(sc, sc_plink);
                 mutex_exit(&pdk->dk_openlock);                  mutex_exit(&pdk->dk_openlock);
   
                   cv_destroy(&sc->sc_dkdrn);
                   mutex_destroy(&sc->sc_iolock);
                 bufq_free(sc->sc_bufq);                  bufq_free(sc->sc_bufq);
                 free(sc, M_DKWEDGE);                  free(sc, M_DKWEDGE);
                 return (ENOMEM);                  return (ENOMEM);
Line 568  dkwedge_detach(device_t self, int flags)
Line 580  dkwedge_detach(device_t self, int flags)
 {  {
         struct dkwedge_softc *sc = NULL;          struct dkwedge_softc *sc = NULL;
         u_int unit;          u_int unit;
         int bmaj, cmaj, rc, s;          int bmaj, cmaj, rc;
   
         rw_enter(&dkwedges_lock, RW_WRITER);          rw_enter(&dkwedges_lock, RW_WRITER);
         for (unit = 0; unit < ndkwedges; unit++) {          for (unit = 0; unit < ndkwedges; unit++) {
Line 600  dkwedge_detach(device_t self, int flags)
Line 612  dkwedge_detach(device_t self, int flags)
          * state of the wedge is not RUNNING.  Once we've done           * state of the wedge is not RUNNING.  Once we've done
          * that, wait for any other pending I/O to complete.           * that, wait for any other pending I/O to complete.
          */           */
         s = splbio();  
         dkstart(sc);          dkstart(sc);
         dkwedge_wait_drain(sc);          dkwedge_wait_drain(sc);
         splx(s);  
   
         /* Nuke the vnodes for any open instances. */          /* Nuke the vnodes for any open instances. */
         vdevgone(bmaj, unit, unit, VBLK);          vdevgone(bmaj, unit, unit, VBLK);
Line 635  dkwedge_detach(device_t self, int flags)
Line 645  dkwedge_detach(device_t self, int flags)
         sc->sc_state = DKW_STATE_DEAD;          sc->sc_state = DKW_STATE_DEAD;
         rw_exit(&dkwedges_lock);          rw_exit(&dkwedges_lock);
   
           mutex_destroy(&sc->sc_iolock);
           cv_destroy(&sc->sc_dkdrn);
   
         free(sc, M_DKWEDGE);          free(sc, M_DKWEDGE);
   
         return 0;          return 0;
Line 1206  dkstrategy(struct buf *bp)
Line 1219  dkstrategy(struct buf *bp)
 {  {
         struct dkwedge_softc *sc = dkwedge_lookup(bp->b_dev);          struct dkwedge_softc *sc = dkwedge_lookup(bp->b_dev);
         uint64_t p_size, p_offset;          uint64_t p_size, p_offset;
         int s;  
   
         if (sc == NULL) {          if (sc == NULL) {
                 bp->b_error = ENODEV;                  bp->b_error = ENODEV;
Line 1234  dkstrategy(struct buf *bp)
Line 1246  dkstrategy(struct buf *bp)
         bp->b_rawblkno = bp->b_blkno + p_offset;          bp->b_rawblkno = bp->b_blkno + p_offset;
   
         /* Place it in the queue and start I/O on the unit. */          /* Place it in the queue and start I/O on the unit. */
         s = splbio();          mutex_enter(&sc->sc_iolock);
         sc->sc_iopend++;          sc->sc_iopend++;
         bufq_put(sc->sc_bufq, bp);          bufq_put(sc->sc_bufq, bp);
           mutex_exit(&sc->sc_iolock);
   
         dkstart(sc);          dkstart(sc);
         splx(s);  
         return;          return;
   
  done:   done:
Line 1250  dkstrategy(struct buf *bp)
Line 1263  dkstrategy(struct buf *bp)
  * dkstart:   * dkstart:
  *   *
  *      Start I/O that has been enqueued on the wedge.   *      Start I/O that has been enqueued on the wedge.
  *      NOTE: Must be called at splbio()!  
  */   */
 static void  static void
 dkstart(struct dkwedge_softc *sc)  dkstart(struct dkwedge_softc *sc)
Line 1258  dkstart(struct dkwedge_softc *sc)
Line 1270  dkstart(struct dkwedge_softc *sc)
         struct vnode *vp;          struct vnode *vp;
         struct buf *bp, *nbp;          struct buf *bp, *nbp;
   
           mutex_enter(&sc->sc_iolock);
   
         /* Do as much work as has been enqueued. */          /* Do as much work as has been enqueued. */
         while ((bp = bufq_peek(sc->sc_bufq)) != NULL) {          while ((bp = bufq_peek(sc->sc_bufq)) != NULL) {
   
                 if (sc->sc_state != DKW_STATE_RUNNING) {                  if (sc->sc_state != DKW_STATE_RUNNING) {
                         (void) bufq_get(sc->sc_bufq);                          (void) bufq_get(sc->sc_bufq);
                         if (sc->sc_iopend-- == 1 &&                          if (sc->sc_iopend-- == 1 &&
                             (sc->sc_flags & DK_F_WAIT_DRAIN) != 0) {                              (sc->sc_flags & DK_F_WAIT_DRAIN) != 0) {
                                 sc->sc_flags &= ~DK_F_WAIT_DRAIN;                                  sc->sc_flags &= ~DK_F_WAIT_DRAIN;
                                 wakeup(&sc->sc_iopend);                                  cv_broadcast(&sc->sc_dkdrn);
                         }                          }
                           mutex_exit(&sc->sc_iolock);
                         bp->b_error = ENXIO;                          bp->b_error = ENXIO;
                         bp->b_resid = bp->b_bcount;                          bp->b_resid = bp->b_bcount;
                         biodone(bp);                          biodone(bp);
                           mutex_enter(&sc->sc_iolock);
                           continue;
                 }                  }
   
                 /* Instrumentation. */                  /* fetch an I/O buf with sc_iolock dropped */
                 disk_busy(&sc->sc_dk);                  mutex_exit(&sc->sc_iolock);
   
                 nbp = getiobuf(sc->sc_parent->dk_rawvp, false);                  nbp = getiobuf(sc->sc_parent->dk_rawvp, false);
                   mutex_enter(&sc->sc_iolock);
                 if (nbp == NULL) {                  if (nbp == NULL) {
                         /*                          /*
                          * No resources to run this request; leave the                           * No resources to run this request; leave the
                          * buffer queued up, and schedule a timer to                           * buffer queued up, and schedule a timer to
                          * restart the queue in 1/2 a second.                           * restart the queue in 1/2 a second.
                          */                           */
                         disk_unbusy(&sc->sc_dk, 0, bp->b_flags & B_READ);  
                         callout_schedule(&sc->sc_restart_ch, hz / 2);                          callout_schedule(&sc->sc_restart_ch, hz / 2);
                         return;                          break;
                 }                  }
   
                 (void) bufq_get(sc->sc_bufq);                  /*
                    * fetch buf, this can fail if another thread
                    * has already processed the queue, it can also
                    * return a completely different buf.
                    */
                   bp = bufq_get(sc->sc_bufq);
                   if (bp == NULL) {
                           mutex_exit(&sc->sc_iolock);
                           putiobuf(nbp);
                           mutex_enter(&sc->sc_iolock);
                           continue;
                   }
   
                   /* Instrumentation. */
                   disk_busy(&sc->sc_dk);
   
                   /* release lock for VOP_STRATEGY */
                   mutex_exit(&sc->sc_iolock);
   
                 nbp->b_data = bp->b_data;                  nbp->b_data = bp->b_data;
                 nbp->b_flags = bp->b_flags;                  nbp->b_flags = bp->b_flags;
Line 1308  dkstart(struct dkwedge_softc *sc)
Line 1342  dkstart(struct dkwedge_softc *sc)
                         mutex_exit(vp->v_interlock);                          mutex_exit(vp->v_interlock);
                 }                  }
                 VOP_STRATEGY(vp, nbp);                  VOP_STRATEGY(vp, nbp);
   
                   mutex_enter(&sc->sc_iolock);
         }          }
   
           mutex_exit(&sc->sc_iolock);
 }  }
   
 /*  /*
Line 1322  dkiodone(struct buf *bp)
Line 1360  dkiodone(struct buf *bp)
         struct buf *obp = bp->b_private;          struct buf *obp = bp->b_private;
         struct dkwedge_softc *sc = dkwedge_lookup(obp->b_dev);          struct dkwedge_softc *sc = dkwedge_lookup(obp->b_dev);
   
         int s = splbio();  
   
         if (bp->b_error != 0)          if (bp->b_error != 0)
                 obp->b_error = bp->b_error;                  obp->b_error = bp->b_error;
         obp->b_resid = bp->b_resid;          obp->b_resid = bp->b_resid;
         putiobuf(bp);          putiobuf(bp);
   
           mutex_enter(&sc->sc_iolock);
         if (sc->sc_iopend-- == 1 && (sc->sc_flags & DK_F_WAIT_DRAIN) != 0) {          if (sc->sc_iopend-- == 1 && (sc->sc_flags & DK_F_WAIT_DRAIN) != 0) {
                 sc->sc_flags &= ~DK_F_WAIT_DRAIN;                  sc->sc_flags &= ~DK_F_WAIT_DRAIN;
                 wakeup(&sc->sc_iopend);                  cv_broadcast(&sc->sc_dkdrn);
         }          }
   
         disk_unbusy(&sc->sc_dk, obp->b_bcount - obp->b_resid,          disk_unbusy(&sc->sc_dk, obp->b_bcount - obp->b_resid,
             obp->b_flags & B_READ);              obp->b_flags & B_READ);
           mutex_exit(&sc->sc_iolock);
   
         biodone(obp);          biodone(obp);
   
         /* Kick the queue in case there is more work we can do. */          /* Kick the queue in case there is more work we can do. */
         dkstart(sc);          dkstart(sc);
         splx(s);  
 }  }
   
 /*  /*
Line 1354  static void
Line 1391  static void
 dkrestart(void *v)  dkrestart(void *v)
 {  {
         struct dkwedge_softc *sc = v;          struct dkwedge_softc *sc = v;
         int s;  
   
         s = splbio();  
         dkstart(sc);          dkstart(sc);
         splx(s);  
 }  }
   
 /*  /*

Legend:
Removed from v.1.91.2.1  
changed lines
  Added in v.1.91.2.2

CVSweb <webmaster@jp.NetBSD.org>