static int vmci_transport_notify_pkt_send_post_enqueue( struct sock *sk, ssize_t written, struct vmci_transport_send_notify_data *data) { int err = 0; struct vsock_sock *vsk; bool sent_wrote = false; bool was_empty; int retries = 0; vsk = vsock_sk(sk); smp_mb(); was_empty = vmci_qpair_produce_buf_ready(vmci_trans(vsk)->qpair) == written; if (was_empty) { while (!(vsk->peer_shutdown & RCV_SHUTDOWN) && !sent_wrote && retries < VMCI_TRANSPORT_MAX_DGRAM_RESENDS) { err = vmci_transport_send_wrote(sk); if (err >= 0) sent_wrote = true; retries++; } } if (retries >= VMCI_TRANSPORT_MAX_DGRAM_RESENDS && !sent_wrote) { pr_err("%p unable to send wrote notification to peer\n", sk); return err; } return err; }
static int VPageChannelSendPacket(VPageChannel *channel, // IN VPageChannelPacket *packet, // IN Bool needsLock, // IN Bool signalPending) // IN { int retval; ssize_t totalSize, sentSize; ssize_t freeSpace; unsigned long flags; ASSERT(channel); if (VPCState_Connected != channel->state) { VMCI_WARNING((LGPFX"Not connected (channel=%p).\n", channel)); return VMCI_ERROR_DST_UNREACHABLE; } ASSERT(packet); totalSize = sizeof(VPageChannelPacket) + packet->msgLen + packet->numElems * sizeof(VPageChannelElem); if (needsLock) { VPageChannelAcquireSendLock(channel, &flags); } else { flags = 0; /* Silence compiler. */ } freeSpace = vmci_qpair_produce_free_space(channel->qpair); if (freeSpace < totalSize) { VMCI_WARNING((LGPFX"No free space in queuepair (channel=%p) " "(required=%"FMTSZ"d) (actual=%"FMTSZ"d).\n", channel, totalSize, freeSpace)); retval = VMCI_ERROR_NO_MEM; goto exit; } sentSize = vmci_qpair_enqueue(channel->qpair, packet, totalSize, 0); if (!signalPending) { if (sentSize == vmci_qpair_produce_buf_ready(channel->qpair)) { retval = VPageChannelSignal(channel); if (retval < VMCI_SUCCESS) { goto exit; } } } if (sentSize < totalSize) { /* * XXX, deal with partial sending. */ VMCI_WARNING((LGPFX"No free space in queuepair (channel=%p) " "(required=%"FMTSZ"d) (actual=%"FMTSZ"d).\n", channel, totalSize, sentSize)); retval = VMCI_ERROR_NO_MEM; goto exit; } VMCI_DEBUG_LOG(10, (LGPFX"Sent packet (channel=%p) (size=%"FMTSZ"d).\n", channel, sentSize)); retval = VMCI_SUCCESS; exit: if (needsLock) { VPageChannelReleaseSendLock(channel, flags); } return retval; }