Author: sephe
Date: Fri Nov 25 09:13:10 2016
New Revision: 309140
URL: https://svnweb.freebsd.org/changeset/base/309140

Log:
  hyperv/vmbus: Add a simplified version of channel close.
  
  So that the caller can know the channel close error and react accordingly.
  
  MFC after:    1 week
  Sponsored by: Microsoft
  Differential Revision:        https://reviews.freebsd.org/D8600

Modified:
  head/sys/dev/hyperv/include/vmbus.h
  head/sys/dev/hyperv/vmbus/vmbus_chan.c

Modified: head/sys/dev/hyperv/include/vmbus.h
==============================================================================
--- head/sys/dev/hyperv/include/vmbus.h Fri Nov 25 08:57:52 2016        
(r309139)
+++ head/sys/dev/hyperv/include/vmbus.h Fri Nov 25 09:13:10 2016        
(r309140)
@@ -131,6 +131,7 @@ vmbus_get_channel(device_t dev)
 
 /*
  * vmbus_chan_open_br()
+ *
  * Return values:
  * 0                   Succeeded.
  * EISCONN             Failed, and the memory passed through 'br' is still
@@ -139,6 +140,24 @@ vmbus_get_channel(device_t dev)
  * other values                Failed.  The memory passed through 'br' is no 
longer
  *                     connected.  Callers are free to do anything with the
  *                     memory passed through 'br'.
+ *
+ *
+ *
+ * vmbus_chan_close_direct()
+ *
+ * NOTE:
+ * Callers of this function _must_ make sure to close all sub-channels before
+ * closing the primary channel.
+ *
+ * Return values:
+ * 0                   Succeeded.
+ * EISCONN             Failed, and the memory associated with the bufring
+ *                     is still connected.  Callers must _not_ free the the
+ *                     memory associated with the bufring, if this error
+ *                     happens.
+ * other values                Failed.  The memory associated with the bufring 
is
+ *                     no longer connected.  Callers are free to do anything
+ *                     with the memory associated with the bufring.
  */
 int            vmbus_chan_open(struct vmbus_channel *chan,
                    int txbr_size, int rxbr_size, const void *udata, int udlen,
@@ -147,6 +166,7 @@ int         vmbus_chan_open_br(struct vmbus_cha
                    const struct vmbus_chan_br *cbr, const void *udata,
                    int udlen, vmbus_chan_callback_t cb, void *cbarg);
 void           vmbus_chan_close(struct vmbus_channel *chan);
+int            vmbus_chan_close_direct(struct vmbus_channel *chan);
 void           vmbus_chan_intr_drain(struct vmbus_channel *chan);
 void           vmbus_chan_run_task(struct vmbus_channel *chan,
                    struct task *task);

Modified: head/sys/dev/hyperv/vmbus/vmbus_chan.c
==============================================================================
--- head/sys/dev/hyperv/vmbus/vmbus_chan.c      Fri Nov 25 08:57:52 2016        
(r309139)
+++ head/sys/dev/hyperv/vmbus/vmbus_chan.c      Fri Nov 25 09:13:10 2016        
(r309140)
@@ -851,6 +851,41 @@ disconnect:
        return (error);
 }
 
+int
+vmbus_chan_close_direct(struct vmbus_channel *chan)
+{
+       int error;
+
+#ifdef INVARIANTS
+       if (VMBUS_CHAN_ISPRIMARY(chan)) {
+               struct vmbus_channel *subchan;
+
+               /*
+                * All sub-channels _must_ have been closed, or are _not_
+                * opened at all.
+                */
+               mtx_lock(&chan->ch_subchan_lock);
+               TAILQ_FOREACH(subchan, &chan->ch_subchans, ch_sublink) {
+                       KASSERT(
+                          (subchan->ch_stflags & VMBUS_CHAN_ST_OPENED) == 0,
+                          ("chan%u: subchan%u is still opened",
+                           chan->ch_id, subchan->ch_subidx));
+               }
+               mtx_unlock(&chan->ch_subchan_lock);
+       }
+#endif
+
+       error = vmbus_chan_close_internal(chan);
+       if (!VMBUS_CHAN_ISPRIMARY(chan)) {
+               /*
+                * This sub-channel is referenced, when it is linked to
+                * the primary channel; drop that reference now.
+                */
+               vmbus_chan_detach(chan);
+       }
+       return (error);
+}
+
 /*
  * Caller should make sure that all sub-channels have
  * been added to 'chan' and all to-be-closed channels
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to