コード例 #1
0
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;
}
コード例 #2
0
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;
}