]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blobdiff - net/rxrpc/ar-internal.h
Merge tag 'pinctrl-v4.9-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw...
[mirror_ubuntu-artful-kernel.git] / net / rxrpc / ar-internal.h
index 034f525f22358deb8d2c020fa3463a0cba28fe65..d38dffd7808536a510a523ad5d3d3032abc4c178 100644 (file)
@@ -93,7 +93,6 @@ struct rxrpc_sock {
        rxrpc_notify_new_call_t notify_new_call; /* Func to notify of new call */
        rxrpc_discard_new_call_t discard_new_call; /* Func to discard a new call */
        struct rxrpc_local      *local;         /* local endpoint */
-       struct hlist_node       listen_link;    /* link in the local endpoint's listen list */
        struct rxrpc_backlog    *backlog;       /* Preallocation for services */
        spinlock_t              incoming_lock;  /* Incoming call vs service shutdown lock */
        struct list_head        sock_calls;     /* List of calls owned by this socket */
@@ -142,15 +141,10 @@ struct rxrpc_host_header {
  */
 struct rxrpc_skb_priv {
        union {
-               unsigned long   resend_at;      /* time in jiffies at which to resend */
-               struct {
-                       u8      nr_jumbo;       /* Number of jumbo subpackets */
-               };
+               u8              nr_jumbo;       /* Number of jumbo subpackets */
        };
        union {
-               unsigned int    offset;         /* offset into buffer of next read */
                int             remain;         /* amount of space remaining for next write */
-               u32             error;          /* network error code */
        };
 
        struct rxrpc_host_header hdr;           /* RxRPC packet header from this packet */
@@ -219,7 +213,7 @@ struct rxrpc_local {
        struct list_head        link;
        struct socket           *socket;        /* my UDP socket */
        struct work_struct      processor;
-       struct hlist_head       services;       /* services listening on this endpoint */
+       struct rxrpc_sock __rcu *service;       /* Service(s) listening on this endpoint */
        struct rw_semaphore     defrag_sem;     /* control re-enablement of IP DF bit */
        struct sk_buff_head     reject_queue;   /* packets awaiting rejection */
        struct sk_buff_head     event_queue;    /* endpoint event packets awaiting processing */
@@ -258,10 +252,12 @@ struct rxrpc_peer {
 
        /* calculated RTT cache */
 #define RXRPC_RTT_CACHE_SIZE 32
-       suseconds_t             rtt;            /* current RTT estimate (in uS) */
-       unsigned int            rtt_point;      /* next entry at which to insert */
-       unsigned int            rtt_usage;      /* amount of cache actually used */
-       suseconds_t             rtt_cache[RXRPC_RTT_CACHE_SIZE]; /* calculated RTT cache */
+       ktime_t                 rtt_last_req;   /* Time of last RTT request */
+       u64                     rtt;            /* Current RTT estimate (in nS) */
+       u64                     rtt_sum;        /* Sum of cache contents */
+       u64                     rtt_cache[RXRPC_RTT_CACHE_SIZE]; /* Determined RTT cache */
+       u8                      rtt_cursor;     /* next entry at which to insert */
+       u8                      rtt_usage;      /* amount of cache actually used */
 };
 
 /*
@@ -385,10 +381,9 @@ struct rxrpc_connection {
        int                     debug_id;       /* debug ID for printks */
        atomic_t                serial;         /* packet serial number counter */
        unsigned int            hi_serial;      /* highest serial number received */
+       u32                     security_nonce; /* response re-use preventer */
        u8                      size_align;     /* data size alignment (for security) */
-       u8                      header_size;    /* rxrpc + security header size */
        u8                      security_size;  /* security header size */
-       u32                     security_nonce; /* response re-use preventer */
        u8                      security_ix;    /* security type */
        u8                      out_clientflag; /* RXRPC_CLIENT_INITIATED if we are client */
 };
@@ -403,6 +398,8 @@ enum rxrpc_call_flag {
        RXRPC_CALL_EXPOSED,             /* The call was exposed to the world */
        RXRPC_CALL_RX_LAST,             /* Received the last packet (at rxtx_top) */
        RXRPC_CALL_TX_LAST,             /* Last packet in Tx buffer (at rxtx_top) */
+       RXRPC_CALL_PINGING,             /* Ping in process */
+       RXRPC_CALL_RETRANS_TIMEOUT,     /* Retransmission due to timeout occurred */
 };
 
 /*
@@ -447,6 +444,17 @@ enum rxrpc_call_completion {
        NR__RXRPC_CALL_COMPLETIONS
 };
 
+/*
+ * Call Tx congestion management modes.
+ */
+enum rxrpc_congest_mode {
+       RXRPC_CALL_SLOW_START,
+       RXRPC_CALL_CONGEST_AVOIDANCE,
+       RXRPC_CALL_PACKET_LOSS,
+       RXRPC_CALL_FAST_RETRANSMIT,
+       NR__RXRPC_CONGEST_MODES
+};
+
 /*
  * RxRPC call definition
  * - matched by { connection, call_id }
@@ -456,9 +464,9 @@ struct rxrpc_call {
        struct rxrpc_connection *conn;          /* connection carrying call */
        struct rxrpc_peer       *peer;          /* Peer record for remote address */
        struct rxrpc_sock __rcu *socket;        /* socket responsible */
-       unsigned long           ack_at;         /* When deferred ACK needs to happen */
-       unsigned long           resend_at;      /* When next resend needs to happen */
-       unsigned long           expire_at;      /* When the call times out */
+       ktime_t                 ack_at;         /* When deferred ACK needs to happen */
+       ktime_t                 resend_at;      /* When next resend needs to happen */
+       ktime_t                 expire_at;      /* When the call times out */
        struct timer_list       timer;          /* Combined event timer */
        struct work_struct      processor;      /* Event processor */
        rxrpc_notify_rx_t       notify_rx;      /* kernel service Rx notification function */
@@ -487,6 +495,8 @@ struct rxrpc_call {
        u32                     call_id;        /* call ID on connection  */
        u32                     cid;            /* connection ID plus channel index */
        int                     debug_id;       /* debug ID for printks */
+       unsigned short          rx_pkt_offset;  /* Current recvmsg packet offset */
+       unsigned short          rx_pkt_len;     /* Current recvmsg packet len */
 
        /* Rx/Tx circular buffer, depending on phase.
         *
@@ -506,6 +516,10 @@ struct rxrpc_call {
 #define RXRPC_TX_ANNO_UNACK    1
 #define RXRPC_TX_ANNO_NAK      2
 #define RXRPC_TX_ANNO_RETRANS  3
+#define RXRPC_TX_ANNO_MASK     0x03
+#define RXRPC_TX_ANNO_LAST     0x04
+#define RXRPC_TX_ANNO_RESENT   0x08
+
 #define RXRPC_RX_ANNO_JUMBO    0x3f            /* Jumbo subpacket number + 1 if not zero */
 #define RXRPC_RX_ANNO_JLAST    0x40            /* Set if last element of a jumbo packet */
 #define RXRPC_RX_ANNO_VERIFIED 0x80            /* Set if verified and decrypted */
@@ -513,6 +527,20 @@ struct rxrpc_call {
                                                 * not hard-ACK'd packet follows this.
                                                 */
        rxrpc_seq_t             tx_top;         /* Highest Tx slot allocated. */
+
+       /* TCP-style slow-start congestion control [RFC5681].  Since the SMSS
+        * is fixed, we keep these numbers in terms of segments (ie. DATA
+        * packets) rather than bytes.
+        */
+#define RXRPC_TX_SMSS          RXRPC_JUMBO_DATALEN
+       u8                      cong_cwnd;      /* Congestion window size */
+       u8                      cong_extra;     /* Extra to send for congestion management */
+       u8                      cong_ssthresh;  /* Slow-start threshold */
+       enum rxrpc_congest_mode cong_mode:8;    /* Congestion management mode */
+       u8                      cong_dup_acks;  /* Count of ACKs showing missing packets */
+       u8                      cong_cumul_acks; /* Cumulative ACK count */
+       ktime_t                 cong_tstamp;    /* Last time cwnd was changed */
+
        rxrpc_seq_t             rx_hard_ack;    /* Dead slot in buffer; the first received but not
                                                 * consumed packet follows this.
                                                 */
@@ -528,11 +556,36 @@ struct rxrpc_call {
        u16                     ackr_skew;      /* skew on packet being ACK'd */
        rxrpc_serial_t          ackr_serial;    /* serial of packet being ACK'd */
        rxrpc_seq_t             ackr_prev_seq;  /* previous sequence number received */
-       unsigned short          rx_pkt_offset;  /* Current recvmsg packet offset */
-       unsigned short          rx_pkt_len;     /* Current recvmsg packet len */
+       rxrpc_seq_t             ackr_consumed;  /* Highest packet shown consumed */
+       rxrpc_seq_t             ackr_seen;      /* Highest packet shown seen */
+       rxrpc_serial_t          ackr_ping;      /* Last ping sent */
+       ktime_t                 ackr_ping_time; /* Time last ping sent */
 
        /* transmission-phase ACK management */
+       ktime_t                 acks_latest_ts; /* Timestamp of latest ACK received */
        rxrpc_serial_t          acks_latest;    /* serial number of latest ACK received */
+       rxrpc_seq_t             acks_lowest_nak; /* Lowest NACK in the buffer (or ==tx_hard_ack) */
+};
+
+/*
+ * Summary of a new ACK and the changes it made to the Tx buffer packet states.
+ */
+struct rxrpc_ack_summary {
+       u8                      ack_reason;
+       u8                      nr_acks;                /* Number of ACKs in packet */
+       u8                      nr_nacks;               /* Number of NACKs in packet */
+       u8                      nr_new_acks;            /* Number of new ACKs in packet */
+       u8                      nr_new_nacks;           /* Number of new NACKs in packet */
+       u8                      nr_rot_new_acks;        /* Number of rotated new ACKs */
+       bool                    new_low_nack;           /* T if new low NACK found */
+       bool                    retrans_timeo;          /* T if reTx due to timeout happened */
+       u8                      flight_size;            /* Number of unreceived transmissions */
+       /* Place to stash values for tracing */
+       enum rxrpc_congest_mode mode:8;
+       u8                      cwnd;
+       u8                      ssthresh;
+       u8                      dup_acks;
+       u8                      cumulative_acks;
 };
 
 enum rxrpc_skb_trace {
@@ -547,7 +600,6 @@ enum rxrpc_skb_trace {
        rxrpc_skb_tx_cleaned,
        rxrpc_skb_tx_freed,
        rxrpc_skb_tx_got,
-       rxrpc_skb_tx_lost,
        rxrpc_skb_tx_new,
        rxrpc_skb_tx_rotated,
        rxrpc_skb_tx_seen,
@@ -618,9 +670,10 @@ extern const char rxrpc_call_traces[rxrpc_call__nr_trace][4];
 enum rxrpc_transmit_trace {
        rxrpc_transmit_wait,
        rxrpc_transmit_queue,
-       rxrpc_transmit_queue_reqack,
        rxrpc_transmit_queue_last,
        rxrpc_transmit_rotate,
+       rxrpc_transmit_rotate_last,
+       rxrpc_transmit_await_reply,
        rxrpc_transmit_end,
        rxrpc_transmit__nr_trace
 };
@@ -656,8 +709,75 @@ enum rxrpc_recvmsg_trace {
 
 extern const char rxrpc_recvmsg_traces[rxrpc_recvmsg__nr_trace][5];
 
+enum rxrpc_rtt_tx_trace {
+       rxrpc_rtt_tx_ping,
+       rxrpc_rtt_tx_data,
+       rxrpc_rtt_tx__nr_trace
+};
+
+extern const char rxrpc_rtt_tx_traces[rxrpc_rtt_tx__nr_trace][5];
+
+enum rxrpc_rtt_rx_trace {
+       rxrpc_rtt_rx_ping_response,
+       rxrpc_rtt_rx_requested_ack,
+       rxrpc_rtt_rx__nr_trace
+};
+
+extern const char rxrpc_rtt_rx_traces[rxrpc_rtt_rx__nr_trace][5];
+
+enum rxrpc_timer_trace {
+       rxrpc_timer_begin,
+       rxrpc_timer_init_for_reply,
+       rxrpc_timer_expired,
+       rxrpc_timer_set_for_ack,
+       rxrpc_timer_set_for_resend,
+       rxrpc_timer_set_for_send,
+       rxrpc_timer__nr_trace
+};
+
+extern const char rxrpc_timer_traces[rxrpc_timer__nr_trace][8];
+
+enum rxrpc_propose_ack_trace {
+       rxrpc_propose_ack_client_tx_end,
+       rxrpc_propose_ack_input_data,
+       rxrpc_propose_ack_ping_for_lost_ack,
+       rxrpc_propose_ack_ping_for_lost_reply,
+       rxrpc_propose_ack_ping_for_params,
+       rxrpc_propose_ack_respond_to_ack,
+       rxrpc_propose_ack_respond_to_ping,
+       rxrpc_propose_ack_retry_tx,
+       rxrpc_propose_ack_rotate_rx,
+       rxrpc_propose_ack_terminal_ack,
+       rxrpc_propose_ack__nr_trace
+};
+
+enum rxrpc_propose_ack_outcome {
+       rxrpc_propose_ack_use,
+       rxrpc_propose_ack_update,
+       rxrpc_propose_ack_subsume,
+       rxrpc_propose_ack__nr_outcomes
+};
+
+extern const char rxrpc_propose_ack_traces[rxrpc_propose_ack__nr_trace][8];
+extern const char *const rxrpc_propose_ack_outcomes[rxrpc_propose_ack__nr_outcomes];
+
+enum rxrpc_congest_change {
+       rxrpc_cong_begin_retransmission,
+       rxrpc_cong_cleared_nacks,
+       rxrpc_cong_new_low_nack,
+       rxrpc_cong_no_change,
+       rxrpc_cong_progress,
+       rxrpc_cong_retransmit_again,
+       rxrpc_cong_rtt_window_end,
+       rxrpc_cong_saw_nack,
+       rxrpc_congest__nr_change
+};
+
+extern const char rxrpc_congest_modes[NR__RXRPC_CONGEST_MODES][10];
+extern const char rxrpc_congest_changes[rxrpc_congest__nr_change][9];
+
 extern const char *const rxrpc_pkts[];
-extern const char *rxrpc_acks(u8 reason);
+extern const char const rxrpc_ack_names[RXRPC_ACK__INVALID + 1][4];
 
 #include <trace/events/rxrpc.h>
 
@@ -685,7 +805,9 @@ int rxrpc_reject_call(struct rxrpc_sock *);
 /*
  * call_event.c
  */
-void rxrpc_propose_ACK(struct rxrpc_call *, u8, u16, u32, bool, bool);
+void rxrpc_set_timer(struct rxrpc_call *, enum rxrpc_timer_trace, ktime_t);
+void rxrpc_propose_ACK(struct rxrpc_call *, u8, u16, u32, bool, bool,
+                      enum rxrpc_propose_ack_trace);
 void rxrpc_process_call(struct work_struct *);
 
 /*
@@ -739,6 +861,7 @@ static inline bool __rxrpc_set_call_completion(struct rxrpc_call *call,
                call->error = error;
                call->completion = compl,
                call->state = RXRPC_CALL_COMPLETE;
+               wake_up(&call->waitq);
                return true;
        }
        return false;
@@ -946,7 +1069,7 @@ extern const s8 rxrpc_ack_priority[];
  * output.c
  */
 int rxrpc_send_call_packet(struct rxrpc_call *, u8);
-int rxrpc_send_data_packet(struct rxrpc_connection *, struct sk_buff *);
+int rxrpc_send_data_packet(struct rxrpc_call *, struct sk_buff *, bool);
 void rxrpc_reject_packets(struct rxrpc_local *);
 
 /*
@@ -954,6 +1077,8 @@ void rxrpc_reject_packets(struct rxrpc_local *);
  */
 void rxrpc_error_report(struct sock *);
 void rxrpc_peer_error_distributor(struct work_struct *);
+void rxrpc_peer_add_rtt(struct rxrpc_call *, enum rxrpc_rtt_rx_trace,
+                       rxrpc_serial_t, rxrpc_serial_t, ktime_t, ktime_t);
 
 /*
  * peer_object.c