Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F142296606
D7626.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D7626.diff
View Options
Index: head/sys/dev/hyperv/utilities/hv_heartbeat.c
===================================================================
--- head/sys/dev/hyperv/utilities/hv_heartbeat.c
+++ head/sys/dev/hyperv/utilities/hv_heartbeat.c
@@ -22,23 +22,22 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
#include <sys/param.h>
-#include <sys/kernel.h>
#include <sys/bus.h>
-#include <sys/malloc.h>
+#include <sys/kernel.h>
#include <sys/module.h>
-#include <sys/timetc.h>
-#include <sys/syscallsubr.h>
#include <sys/systm.h>
#include <dev/hyperv/include/hyperv.h>
#include <dev/hyperv/include/vmbus.h>
-#include <dev/hyperv/utilities/hv_utilreg.h>
-#include "hv_util.h"
+#include <dev/hyperv/utilities/hv_util.h>
+#include <dev/hyperv/utilities/vmbus_icreg.h>
+
#include "vmbus_if.h"
static const struct vmbus_ic_desc vmbus_heartbeat_descs[] = {
@@ -51,55 +50,64 @@
VMBUS_IC_DESC_END
};
-/**
- * Process heartbeat message
- */
static void
-hv_heartbeat_cb(struct vmbus_channel *channel, void *context)
+vmbus_heartbeat_cb(struct vmbus_channel *chan, void *xsc)
{
- uint8_t* buf;
- int recvlen;
- uint64_t requestid;
- int ret;
-
- struct hv_vmbus_heartbeat_msg_data* heartbeat_msg;
- struct hv_vmbus_icmsg_hdr* icmsghdrp;
- hv_util_sc *softc;
-
- softc = (hv_util_sc*)context;
- buf = softc->receive_buffer;
-
- recvlen = softc->ic_buflen;
- ret = vmbus_chan_recv(channel, buf, &recvlen, &requestid);
- KASSERT(ret != ENOBUFS, ("hvheartbeat recvbuf is not large enough"));
- /* XXX check recvlen to make sure that it contains enough data */
-
- if ((ret == 0) && recvlen > 0) {
-
- icmsghdrp = (struct hv_vmbus_icmsg_hdr *)
- &buf[sizeof(struct hv_vmbus_pipe_hdr)];
-
- if (icmsghdrp->icmsgtype == HV_ICMSGTYPE_NEGOTIATE) {
- int error;
+ struct hv_util_sc *sc = xsc;
+ struct vmbus_icmsg_hdr *hdr;
+ int dlen, error;
+ uint64_t xactid;
+ void *data;
+
+ /*
+ * Receive request.
+ */
+ data = sc->receive_buffer;
+ dlen = sc->ic_buflen;
+ error = vmbus_chan_recv(chan, data, &dlen, &xactid);
+ KASSERT(error != ENOBUFS, ("icbuf is not large enough"));
+ if (error)
+ return;
+
+ if (dlen < sizeof(struct vmbus_icmsg_hdr)) {
+ device_printf(sc->ic_dev, "invalid data len %d\n", dlen);
+ return;
+ }
+ hdr = data;
- error = vmbus_ic_negomsg(softc, buf, recvlen);
+ /*
+ * Update request, which will be echoed back as response.
+ */
+ switch (hdr->ic_type) {
+ case VMBUS_ICMSG_TYPE_NEGOTIATE:
+ error = vmbus_ic_negomsg(sc, data, dlen);
if (error)
return;
- } else {
- heartbeat_msg =
- (struct hv_vmbus_heartbeat_msg_data *)
- &buf[sizeof(struct hv_vmbus_pipe_hdr) +
- sizeof(struct hv_vmbus_icmsg_hdr)];
-
- heartbeat_msg->seq_num += 1;
- }
+ break;
- icmsghdrp->icflags = HV_ICMSGHDRFLAG_TRANSACTION |
- HV_ICMSGHDRFLAG_RESPONSE;
-
- vmbus_chan_send(channel, VMBUS_CHANPKT_TYPE_INBAND, 0,
- buf, recvlen, requestid);
+ case VMBUS_ICMSG_TYPE_HEARTBEAT:
+ /* Only ic_seq is a must */
+ if (dlen < VMBUS_ICMSG_HEARTBEAT_SIZE_MIN) {
+ device_printf(sc->ic_dev, "invalid heartbeat len %d\n",
+ dlen);
+ return;
+ }
+ ((struct vmbus_icmsg_heartbeat *)data)->ic_seq++;
+ break;
+
+ default:
+ device_printf(sc->ic_dev, "got 0x%08x icmsg\n", hdr->ic_type);
+ break;
}
+
+ /*
+ * Send response by echoing the updated request back.
+ */
+ hdr->ic_flags = VMBUS_ICMSG_FLAG_XACT | VMBUS_ICMSG_FLAG_RESP;
+ error = vmbus_chan_send(chan, VMBUS_CHANPKT_TYPE_INBAND, 0,
+ data, dlen, xactid);
+ if (error)
+ device_printf(sc->ic_dev, "resp send failed: %d\n", error);
}
static int
@@ -112,7 +120,8 @@
static int
hv_heartbeat_attach(device_t dev)
{
- return hv_util_attach(dev, hv_heartbeat_cb);
+
+ return (hv_util_attach(dev, vmbus_heartbeat_cb));
}
static device_method_t heartbeat_methods[] = {
Index: head/sys/dev/hyperv/utilities/vmbus_icreg.h
===================================================================
--- head/sys/dev/hyperv/utilities/vmbus_icreg.h
+++ head/sys/dev/hyperv/utilities/vmbus_icreg.h
@@ -81,4 +81,14 @@
uint32_t ic_ver[];
} __packed;
+/* VMBUS_ICMSG_TYPE_HEARTBEAT */
+struct vmbus_icmsg_heartbeat {
+ struct vmbus_icmsg_hdr ic_hdr;
+ uint64_t ic_seq;
+ uint32_t ic_rsvd[8];
+} __packed;
+
+#define VMBUS_ICMSG_HEARTBEAT_SIZE_MIN \
+ __offsetof(struct vmbus_icmsg_heartbeat, ic_rsvd[0])
+
#endif /* !_VMBUS_ICREG_H_ */
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Jan 19, 7:21 AM (13 h, 27 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27735665
Default Alt Text
D7626.diff (4 KB)
Attached To
Mode
D7626: hyperv/ic: Cleanup heartbeat channel callback.
Attached
Detach File
Event Timeline
Log In to Comment