/* * Copy data from receive ring and change index * NOTE: * We assume (dlen + skip) == sizeof(channel packet). */ int vmbus_rxbr_read(struct vmbus_br *rbr, void *data, size_t dlen, size_t skip) { struct vmbus_bufring *vbr = rbr->vbr; uint32_t br_dsize = rbr->dsize; uint32_t rindex; if (vmbus_br_availread(rbr) < dlen + skip + sizeof(uint64_t)) return -EAGAIN; /* Record where host was when we started read (for debug) */ rbr->windex = rbr->vbr->windex; /* * Copy channel packet from RX bufring. */ rindex = vmbus_br_idxinc(rbr->vbr->rindex, skip, br_dsize); rindex = vmbus_rxbr_copyfrom(rbr, rindex, data, dlen); /* * Discard this channel packet's 64bits offset, which is useless to us. */ rindex = vmbus_br_idxinc(rindex, sizeof(uint64_t), br_dsize); /* Update the read index _after_ the channel packet is fetched. */ rte_compiler_barrier(); vbr->rindex = rindex; return 0; }
/* Copy data from receive ring but don't change index */ int vmbus_rxbr_peek(const struct vmbus_br *rbr, void *data, size_t dlen) { uint32_t avail; /* * The requested data and the 64bits channel packet * offset should be there at least. */ avail = vmbus_br_availread(rbr); if (avail < dlen + sizeof(uint64_t)) return -EAGAIN; vmbus_rxbr_copyfrom(rbr, rbr->vbr->rindex, data, dlen); return 0; }
static void vmbus_dump_ring(FILE *f, const char *id, const struct vmbus_br *br) { const struct vmbus_bufring *vbr = br->vbr; struct vmbus_chanpkt_hdr pkt; fprintf(f, "%s windex=%u rindex=%u mask=%u pending=%u feature=%#x\n", id, vbr->windex, vbr->rindex, vbr->imask, vbr->pending_send, vbr->feature_bits.value); fprintf(f, " size=%u avail write=%u read=%u\n", br->dsize, vmbus_br_availwrite(br, vbr->windex), vmbus_br_availread(br)); if (vmbus_rxbr_peek(br, &pkt, sizeof(pkt)) == 0) fprintf(f, " pkt type %#x len %u flags %#x xactid %#"PRIx64"\n", pkt.type, pkt.tlen << VMBUS_CHANPKT_SIZE_SHIFT, pkt.flags, pkt.xactid); }