1. 06 10月, 2016 5 次提交
  2. 30 9月, 2016 12 次提交
    • D
      rxrpc: Fix the call timer handling · 405dea1d
      David Howells 提交于
      The call timer's concept of a call timeout (of which there are three) that
      is inactive is that it is the timeout has the same expiration time as the
      call expiration timeout (the expiration timer is never inactive).  However,
      I'm not resetting the timeouts when they expire, leading to repeated
      processing of expired timeouts when other timeout events occur.
      
      Fix this by:
      
       (1) Move the timer expiry detection into rxrpc_set_timer() inside the
           locked section.  This means that if a timeout is set that will expire
           immediately, we deal with it immediately.
      
       (2) If a timeout is at or before now then it has expired.  When an expiry
           is detected, an event is raised, the timeout is automatically
           inactivated and the event processor is queued.
      
       (3) If a timeout is at or after the expiry timeout then it is inactive.
           Inactive timeouts do not contribute to the timer setting.
      
       (4) The call timer callback can now just call rxrpc_set_timer() to handle
           things.
      
       (5) The call processor work function now checks the event flags rather
           than checking the timeouts directly.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      405dea1d
    • D
      rxrpc: Keep the call timeouts as ktimes rather than jiffies · df0adc78
      David Howells 提交于
      Keep that call timeouts as ktimes rather than jiffies so that they can be
      expressed as functions of RTT.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      df0adc78
    • D
      rxrpc: Remove error from struct rxrpc_skb_priv as it is unused · c31410ea
      David Howells 提交于
      Remove error from struct rxrpc_skb_priv as it is no longer used.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      c31410ea
    • D
      rxrpc: The offset field in struct rxrpc_skb_priv is unnecessary · 775e5b71
      David Howells 提交于
      The offset field in struct rxrpc_skb_priv is unnecessary as the value can
      always be calculated.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      775e5b71
    • D
      rxrpc: Reduce ssthresh to peer's receive window · 08511150
      David Howells 提交于
      When we receive an ACK from the peer that tells us what the peer's receive
      window (rwind) is, we should reduce ssthresh to rwind if rwind is smaller
      than ssthresh.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      
      08511150
    • D
      rxrpc: Switch to Congestion Avoidance mode at cwnd==ssthresh · 8782def2
      David Howells 提交于
      Switch to Congestion Avoidance mode at cwnd == ssthresh rather than relying
      on cwnd getting incremented beyond ssthresh and the window size, the mode
      being shifted and then cwnd being corrected.
      
      We need to make sure we switch into CA mode so that we stop marking every
      packet for ACK.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      8782def2
    • D
      rxrpc: Note serial number being ACK'd in the congestion management trace · ed1e8679
      David Howells 提交于
      Note the serial number of the packet being ACK'd in the congestion
      management trace rather than the serial number of the ACK packet.  Whilst
      the serial number of the ACK packet is useful for matching ACK packet in
      the output of wireshark, the serial number that the ACK is in response to
      is of more use in working out how different trace lines relate.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      ed1e8679
    • D
      rxrpc: Request more ACKs in slow-start mode · b112a670
      David Howells 提交于
      Set the request-ACK on more DATA packets whilst we're in slow start mode so
      that we get sufficient ACKs back to supply information to configure the
      window.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      b112a670
    • D
      rxrpc: Reduce the rxrpc_local::services list to a pointer · 1e9e5c95
      David Howells 提交于
      Reduce the rxrpc_local::services list to just a pointer as we don't permit
      multiple service endpoints to bind to a single transport endpoints (this is
      excluded by rxrpc_lookup_local()).
      
      The reason we don't allow this is that if you send a request to an AFS
      filesystem service, it will try to talk back to your cache manager on the
      port you sent from (this is how file change notifications are handled).  To
      prevent someone from stealing your CM callbacks, we don't let AF_RXRPC
      sockets share a UDP socket if at least one of them has a service bound.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      1e9e5c95
    • D
      rxrpc: When activating client conn channels, do state check inside lock · 2629c7fa
      David Howells 提交于
      In rxrpc_activate_channels(), the connection cache state is checked outside
      of the lock, which means it can change whilst we're waking calls up,
      thereby changing whether or not we're allowed to wake calls up.
      
      Fix this by moving the check inside the locked region.  The check to see if
      all the channels are currently busy can stay outside of the locked region.
      
      Whilst we're at it:
      
       (1) Split the locked section out into its own function so that we can call
           it from other places in a later patch.
      
       (2) Determine the mask of channels dependent on the state as we're going
           to add another state in a later patch that will restrict the number of
           simultaneous calls to 1 on a connection.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      2629c7fa
    • D
      rxrpc: Make Tx loss-injection go through normal return and adjust tracing · a1767077
      David Howells 提交于
      In rxrpc_send_data_packet() make the loss-injection path return through the
      same code as the transmission path so that the RTT determination is
      initiated and any future timer shuffling will be done, despite the packet
      having been binned.
      
      Whilst we're at it:
      
       (1) Add to the tx_data tracepoint an indication of whether or not we're
           retransmitting a data packet.
      
       (2) When we're deciding whether or not to request an ACK, rather than
           checking if we're in fast-retransmit mode check instead if we're
           retransmitting.
      
       (3) Don't invoke the lose_skb tracepoint when losing a Tx packet as we're
           not altering the sk_buff refcount nor are we just seeing it after
           getting it off the Tx list.
      
       (4) The rxrpc_skb_tx_lost note is then no longer used so remove it.
      
       (5) rxrpc_lose_skb() no longer needs to deal with rxrpc_skb_tx_lost.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      a1767077
    • D
      rxrpc: Fix exclusive client connections · 8732db67
      David Howells 提交于
      Exclusive connections are currently reusable (which they shouldn't be)
      because rxrpc_alloc_client_connection() checks the exclusive flag in the
      rxrpc_connection struct before it's initialised from the function
      parameters.  This means that the DONT_REUSE flag doesn't get set.
      
      Fix this by checking the function parameters for the exclusive flag.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      8732db67
  3. 25 9月, 2016 8 次提交
    • D
      rxrpc: Implement slow-start · 57494343
      David Howells 提交于
      Implement RxRPC slow-start, which is similar to RFC 5681 for TCP.  A
      tracepoint is added to log the state of the congestion management algorithm
      and the decisions it makes.
      
      Notes:
      
       (1) Since we send fixed-size DATA packets (apart from the final packet in
           each phase), counters and calculations are in terms of packets rather
           than bytes.
      
       (2) The ACK packet carries the equivalent of TCP SACK.
      
       (3) The FLIGHT_SIZE calculation in RFC 5681 doesn't seem particularly
           suited to SACK of a small number of packets.  It seems that, almost
           inevitably, by the time three 'duplicate' ACKs have been seen, we have
           narrowed the loss down to one or two missing packets, and the
           FLIGHT_SIZE calculation ends up as 2.
      
       (4) In rxrpc_resend(), if there was no data that apparently needed
           retransmission, we transmit a PING ACK to ask the peer to tell us what
           its Rx window state is.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      57494343
    • D
      rxrpc: Schedule an ACK if the reply to a client call appears overdue · 0d967960
      David Howells 提交于
      If we've sent all the request data in a client call but haven't seen any
      sign of the reply data yet, schedule an ACK to be sent to the server to
      find out if the reply data got lost.
      
      If the server hasn't yet hard-ACK'd the request data, we send a PING ACK to
      demand a response to find out whether we need to retransmit.
      
      If the server says it has received all of the data, we send an IDLE ACK to
      tell the server that we haven't received anything in the receive phase as
      yet.
      
      To make this work, a non-immediate PING ACK must carry a delay.  I've chosen
      the same as the IDLE ACK for the moment.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      0d967960
    • D
      rxrpc: Generate a summary of the ACK state for later use · 31a1b989
      David Howells 提交于
      Generate a summary of the Tx buffer packet state when an ACK is received
      for use in a later patch that does congestion management.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      31a1b989
    • D
      rxrpc: Delay the resend timer to allow for nsec->jiffies conv error · df0562a7
      David Howells 提交于
      When determining the resend timer value, we have a value in nsec but the
      timer is in jiffies which may be a million or more times more coarse.
      nsecs_to_jiffies() rounds down - which means that the resend timeout
      expressed as jiffies is very likely earlier than the one expressed as
      nanoseconds from which it was derived.
      
      The problem is that rxrpc_resend() gets triggered by the timer, but can't
      then find anything to resend yet.  It sets the timer again - but gets
      kicked off immediately again and again until the nanosecond-based expiry
      time is reached and we actually retransmit.
      
      Fix this by adding 1 to the jiffies-based resend_at value to counteract the
      rounding and make sure that the timer happens after the nanosecond-based
      expiry is passed.
      
      Alternatives would be to adjust the timestamp on the packets to align
      with the jiffie scale or to switch back to using jiffie-timestamps.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      df0562a7
    • D
      rxrpc: Reinitialise the call ACK and timer state for client reply phase · dd7c1ee5
      David Howells 提交于
      Clear the ACK reason, ACK timer and resend timer when entering the client
      reply phase when the first DATA packet is received.  New ACKs will be
      proposed once the data is queued.
      
      The resend timer is no longer relevant and we need to cancel ACKs scheduled
      to probe for a lost reply.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      dd7c1ee5
    • D
      rxrpc: Include the last reply DATA serial number in the final ACK · b69d94d7
      David Howells 提交于
      In a client call, include the serial number of the last DATA packet of the
      reply in the final ACK.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      b69d94d7
    • D
      rxrpc: Send an immediate ACK if we fill in a hole · a7056c5b
      David Howells 提交于
      Send an immediate ACK if we fill in a hole in the buffer left by an
      out-of-sequence packet.  This may allow the congestion management in the peer
      to avoid a retransmission if packets got reordered on the wire.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      a7056c5b
    • D
      rxrpc: Send an ACK after every few DATA packets we receive · 805b21b9
      David Howells 提交于
      Send an ACK if we haven't sent one for the last two packets we've received.
      This keeps the other end apprised of where we've got to - which is
      important if they're doing slow-start.
      
      We do this in recvmsg so that we can dispatch a packet directly without the
      need to wake up the background thread.
      
      This should possibly be made configurable in future.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      805b21b9
  4. 23 9月, 2016 15 次提交
    • D
      rxrpc: Add a tracepoint to log which packets will be retransmitted · c6672e3f
      David Howells 提交于
      Add a tracepoint to log in rxrpc_resend() which packets will be
      retransmitted.  Note that if a positive ACK comes in whilst we have dropped
      the lock to retransmit another packet, the actual retransmission may not
      happen, though some of the effects will (such as altering the congestion
      management).
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      c6672e3f
    • D
      rxrpc: Add tracepoint for ACK proposal · 9c7ad434
      David Howells 提交于
      Add a tracepoint to log proposed ACKs, including whether the proposal is
      used to update a pending ACK or is discarded in favour of an easlier,
      higher priority ACK.
      
      Whilst we're at it, get rid of the rxrpc_acks() function and access the
      name array directly.  We do, however, need to validate the ACK reason
      number given to trace_rxrpc_rx_ack() to make sure we don't overrun the
      array.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      9c7ad434
    • D
      rxrpc: Add a tracepoint to log injected Rx packet loss · 89b475ab
      David Howells 提交于
      Add a tracepoint to log received packets that get discarded due to Rx
      packet loss.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      89b475ab
    • D
      rxrpc: Add data Tx tracepoint and adjust Tx ACK tracepoint · be832aec
      David Howells 提交于
      Add a tracepoint to log transmission of DATA packets (including loss
      injection).
      
      Adjust the ACK transmission tracepoint to include the packet serial number
      and to line this up with the DATA transmission display.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      be832aec
    • D
      rxrpc: Add a tracepoint for the call timer · fc7ab6d2
      David Howells 提交于
      Add a tracepoint to log call timer initiation, setting and expiry.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      fc7ab6d2
    • D
      rxrpc: Don't call the tx_ack tracepoint if don't generate an ACK · b86e218e
      David Howells 提交于
      rxrpc_send_call_packet() is invoking the tx_ack tracepoint before it checks
      whether there's an ACK to transmit (another thread may jump in and transmit
      it).
      
      Fix this by only invoking the tracepoint if we get a valid ACK to transmit.
      
      Further, only allocate a serial number if we're going to actually transmit
      something.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      b86e218e
    • D
      rxrpc: Pass the last Tx packet marker in the annotation buffer · 70790dbe
      David Howells 提交于
      When the last packet of data to be transmitted on a call is queued, tx_top
      is set and then the RXRPC_CALL_TX_LAST flag is set.  Unfortunately, this
      leaves a race in the ACK processing side of things because the flag affects
      the interpretation of tx_top and also allows us to start receiving reply
      data before we've finished transmitting.
      
      To fix this, make the following changes:
      
       (1) rxrpc_queue_packet() now sets a marker in the annotation buffer
           instead of setting the RXRPC_CALL_TX_LAST flag.
      
       (2) rxrpc_rotate_tx_window() detects the marker and sets the flag in the
           same context as the routines that use it.
      
       (3) rxrpc_end_tx_phase() is simplified to just shift the call state.
           The Tx window must have been rotated before calling to discard the
           last packet.
      
       (4) rxrpc_receiving_reply() is added to handle the arrival of the first
           DATA packet of a reply to a client call (which is an implicit ACK of
           the Tx phase).
      
       (5) The last part of rxrpc_input_ack() is reordered to perform Tx
           rotation, then soft-ACK application and then to end the phase if we've
           rotated the last packet.  In the event of a terminal ACK, the soft-ACK
           application will be skipped as nAcks should be 0.
      
       (6) rxrpc_input_ackall() now has to rotate as well as ending the phase.
      
      In addition:
      
       (7) Alter the transmit tracepoint to log the rotation of the last packet.
      
       (8) Remove the no-longer relevant queue_reqack tracepoint note.  The
           ACK-REQUESTED packet header flag is now set as needed when we actually
           transmit the packet and may vary by retransmission.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      70790dbe
    • D
      rxrpc: Fix call timer · 01a88f7f
      David Howells 提交于
      Fix the call timer in the following ways:
      
       (1) If call->resend_at or call->ack_at are before or equal to the current
           time, then ignore that timeout.
      
       (2) If call->expire_at is before or equal to the current time, then don't
           set the timer at all (possibly we should queue the call).
      
       (3) Don't skip modifying the timer if timer_pending() is true.  This
           indicates that the timer is working, not that it has expired and is
           running/waiting to run its expiry handler.
      
      Also call rxrpc_set_timer() to start the call timer going rather than
      calling add_timer().
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      01a88f7f
    • D
      rxrpc: Fix accidental cancellation of scheduled resend by ACK parser · be8aa338
      David Howells 提交于
      When rxrpc_input_soft_acks() is parsing the soft-ACKs from an ACK packet,
      it updates the Tx packet annotations in the annotation buffer.  If a
      soft-ACK is an ACK, then we overwrite unack'd, nak'd or to-be-retransmitted
      states and that is fine; but if the soft-ACK is an NACK, we overwrite the
      to-be-retransmitted with a nak - which isn't.
      
      Instead, we need to let any scheduled retransmission stand if the packet
      was NAK'd.
      
      Note that we don't reissue a resend if the annotation is in the
      to-be-retransmitted state because someone else must've scheduled the
      resend already.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      be8aa338
    • D
      rxrpc: Need to start the resend timer on initial transmission · dfc3da44
      David Howells 提交于
      When a DATA packet has its initial transmission, we may need to start or
      adjust the resend timer.  Without this we end up relying on being sent a
      NACK to initiate the resend.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      dfc3da44
    • D
      rxrpc: Use before_eq() and friends to compare serial numbers · 98dafac5
      David Howells 提交于
      before_eq() and friends should be used to compare serial numbers (when not
      checking for (non)equality) rather than casting to int, subtracting and
      checking the result.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      98dafac5
    • D
      rxrpc: Should be using ktime_add_ms() not ktime_add_ns() · 90bd684d
      David Howells 提交于
      ktime_add_ms() should be used to add the resend time (in ms) rather than
      ktime_add_ns().
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      90bd684d
    • D
      rxrpc: Make sure sendmsg() is woken on call completion · c0d058c2
      David Howells 提交于
      Make sure that sendmsg() gets woken up if the call it is waiting for
      completes abnormally.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      c0d058c2
    • D
      rxrpc: Don't send an ACK at the end of service call response transmission · 9aff212b
      David Howells 提交于
      Don't send an IDLE ACK at the end of the transmission of the response to a
      service call.  The service end resends DATA packets until the client sends an
      ACK that hard-acks all the send data.  At that point, the call is complete.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      9aff212b
    • D
      rxrpc: Preset timestamp on Tx sk_buffs · b24d2891
      David Howells 提交于
      Set the timestamp on sk_buffs holding packets to be transmitted before
      queueing them because the moment the packet is on the queue it can be seen
      by the retransmission algorithm - which may see a completely random
      timestamp.
      
      If the retransmission algorithm sees such a timestamp, it may retransmit
      the packet and, in future, tell the congestion management algorithm that
      the retransmit timer expired.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      b24d2891