if (!PKT_FIELD(vsk, peer_waiting_write)) returnfalse;
#ifdef VSOCK_OPTIMIZATION_FLOW_CONTROL /* When the sender blocks, we take that as a sign that the sender is *fasterthanthereceiver.Toreducethetransmitrateofthesender, *wedelaythesendingofthereadnotificationbydecreasingthe *write_notify_window.Thenotificationisdelayeduntilthenumberof *bytesusedinthequeuedropsbelowthewrite_notify_window.
*/
/* For now we ignore the wait information and just see if the free *spaceexceedsthenotifylimit.Notethatimprovingthisfunction *tobemoreintelligentwillnotrequireaprotocolchangeandwill *retaincompatibilitybetweenendpointswithmixedversionsofthis *function. * *Thenotify_limitisusedtodelaynotificationsinthecasewhere *flowcontrolisenabled.Belowthetestisexpressedintermsof *freespaceinthequeue:iffree_space>ConsumeSize- *write_notify_windowthennotifyAnalternatewayofexpressingthis *istorewritetheexpressiontousethedatareadyinthereceive *queue:ifwrite_notify_window>bufferReadythennotifyas *free_space==ConsumeSize-bufferReady.
*/
retval = vmci_qpair_consume_free_space(vmci_trans(vsk)->qpair) >
notify_limit; #ifdef VSOCK_OPTIMIZATION_FLOW_CONTROL if (retval) { /* *Oncewenotifythepeer,weresetthedetectedflagsothe *nextwaitwillagaincauseadecreaseinthewindowsize.
*/
staticbool vmci_transport_notify_waiting_read(struct vsock_sock *vsk)
{ #ifdefined(VSOCK_OPTIMIZATION_WAITING_NOTIFY) if (!PKT_FIELD(vsk, peer_waiting_read)) returnfalse;
/* For now we ignore the wait information and just see if there is any *dataforourpeertoread.Notethatimprovingthisfunctiontobe *moreintelligentwillnotrequireaprotocolchangeandwillretain *compatibilitybetweenendpointswithmixedversionsofthis *function.
*/ return vmci_qpair_produce_buf_ready(vmci_trans(vsk)->qpair) > 0; #else returntrue; #endif
}
if (vmci_transport_notify_waiting_write(vsk)) { /* Notify the peer that we have read, retrying the send on *failureuptoourmaximumvalue.XXXFornowwejustlog *thefailure,butlaterweshouldscheduleaworkitemto *handletheresenduntilitsucceeds.Thatwouldrequire *keepingtrackofworkitemsinthevskandcleaningthemup *uponsocketclose.
*/ while (!(vsk->peer_shutdown & RCV_SHUTDOWN) &&
!sent_read &&
retries < VMCI_TRANSPORT_MAX_DGRAM_RESENDS) {
err = vmci_transport_send_read(sk); if (err >= 0)
sent_read = true;
retries++;
}
if (retries >= VMCI_TRANSPORT_MAX_DGRAM_RESENDS)
pr_err("%p unable to send read notify to peer\n", sk); else #ifdefined(VSOCK_OPTIMIZATION_WAITING_NOTIFY)
PKT_FIELD(vsk, peer_waiting_write) = false; #endif
if (vsock_stream_has_data(vsk) >= target) {
*data_ready_now = true;
} else { /* We can't read right now because there is not enough data *inthequeue.Askfornotificationswhenthereissomething *toread.
*/ if (sk->sk_state == TCP_ESTABLISHED) { if (!send_waiting_read(sk, 1)) return -1;
if (PKT_FIELD(vsk, write_notify_min_window) < target + 1) {
PKT_FIELD(vsk, write_notify_min_window) = target + 1; if (PKT_FIELD(vsk, write_notify_window) <
PKT_FIELD(vsk, write_notify_min_window)) { /* If the current window is smaller than the new *minimalwindowsize,weneedtoreevaluatewhether *weneedtonotifythesender.Ifthenumberofready *bytesaresmallerthanthenewwindow,weneedto *sendanotificationtothesenderbeforeweblock.
*/
/* Notify our peer that we are waiting for data to read. */ if (!send_waiting_read(sk, target)) {
err = -EHOSTUNREACH; return err;
} #ifdef VSOCK_OPTIMIZATION_FLOW_CONTROL if (data->notify_on_block) {
err = vmci_transport_send_read_notification(sk); if (err < 0) return err;
/* Now consume up to len bytes from the queue. Note that since we have *thesocketlockedweshouldcopyatleastreadybytes.
*/ #ifdefined(VSOCK_OPTIMIZATION_WAITING_NOTIFY)
vmci_qpair_get_consume_indexes(vmci_trans(vsk)->qpair,
&data->produce_tail,
&data->consume_head); #endif
staticint
vmci_transport_notify_pkt_send_pre_block( struct sock *sk, struct vmci_transport_send_notify_data *data)
{ /* Notify our peer that we are waiting for room to write. */ if (!send_waiting_write(sk, 1)) return -EHOSTUNREACH;
#ifdefined(VSOCK_OPTIMIZATION_WAITING_NOTIFY) /* Detect a wrap-around to maintain queue generation. Note that this *issafesinceweholdthesocketlockacrossthetwoqueuepair *operations.
*/ if (written >= vmci_trans(vsk)->produce_size - data->produce_tail)
PKT_FIELD(vsk, produce_q_generation)++;
#endif
if (vmci_transport_notify_waiting_read(vsk)) { /* Notify the peer that we have written, retrying the send on *failureuptoourmaximumvalue.SeetheXXXcommentforthe *correspondingpieceofcodeinStreamRecvmsg()forpotential *improvements.
*/ 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) {
pr_err("%p unable to send wrote notify to peer\n", sk); return err;
} else { #ifdefined(VSOCK_OPTIMIZATION_WAITING_NOTIFY)
PKT_FIELD(vsk, peer_waiting_read) = false; #endif
}
} return err;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.