• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *
3  * Copyright 2018 gRPC authors.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 #ifndef GRPC_CORE_LIB_IOMGR_BUFFER_LIST_H
20 #define GRPC_CORE_LIB_IOMGR_BUFFER_LIST_H
21 
22 #include <grpc/support/port_platform.h>
23 
24 #include "absl/types/optional.h"
25 
26 #include "src/core/lib/iomgr/port.h"
27 
28 #include <grpc/support/time.h>
29 
30 #include "src/core/lib/gprpp/memory.h"
31 #include "src/core/lib/iomgr/error.h"
32 #include "src/core/lib/iomgr/internal_errqueue.h"
33 
34 namespace grpc_core {
35 
36 struct ConnectionMetrics {
37   /* Delivery rate in Bytes/s. */
38   absl::optional<uint64_t> delivery_rate;
39   /* If the delivery rate is limited by the application, this is set to true. */
40   absl::optional<bool> is_delivery_rate_app_limited;
41   /* Total packets retransmitted. */
42   absl::optional<uint32_t> packet_retx;
43   /* Total packets retransmitted spuriously. This metric is smaller than or
44   equal to packet_retx. */
45   absl::optional<uint32_t> packet_spurious_retx;
46   /* Total packets sent. */
47   absl::optional<uint32_t> packet_sent;
48   /* Total packets delivered. */
49   absl::optional<uint32_t> packet_delivered;
50   /* Total packets delivered with ECE marked. This metric is smaller than or
51   equal to packet_delivered. */
52   absl::optional<uint32_t> packet_delivered_ce;
53   /* Total bytes lost so far. */
54   absl::optional<uint64_t> data_retx;
55   /* Total bytes sent so far. */
56   absl::optional<uint64_t> data_sent;
57   /* Total bytes in write queue but not sent. */
58   absl::optional<uint64_t> data_notsent;
59   /* Pacing rate of the connection in Bps */
60   absl::optional<uint64_t> pacing_rate;
61   /* Minimum RTT observed in usec. */
62   absl::optional<uint32_t> min_rtt;
63   /* Smoothed RTT in usec */
64   absl::optional<uint32_t> srtt;
65   /* Send congestion window. */
66   absl::optional<uint32_t> congestion_window;
67   /* Slow start threshold in packets. */
68   absl::optional<uint32_t> snd_ssthresh;
69   /* Maximum degree of reordering (i.e., maximum number of packets reodered)
70    on the connection. */
71   absl::optional<uint32_t> reordering;
72   /* Represents the number of recurring retransmissions of the first sequence
73   that is not acknowledged yet. */
74   absl::optional<uint8_t> recurring_retrans;
75   /* The cumulative time (in usec) that the transport protocol was busy
76    sending data. */
77   absl::optional<uint64_t> busy_usec;
78   /* The cumulative time (in usec) that the transport protocol was limited by
79    the receive window size. */
80   absl::optional<uint64_t> rwnd_limited_usec;
81   /* The cumulative time (in usec) that the transport protocol was limited by
82    the send buffer size. */
83   absl::optional<uint64_t> sndbuf_limited_usec;
84 };
85 
86 struct Timestamp {
87   gpr_timespec time;
88   ConnectionMetrics metrics; /* Metrics collected with this timestamp */
89 };
90 
91 struct Timestamps {
92   Timestamp sendmsg_time;
93   Timestamp scheduled_time;
94   Timestamp sent_time;
95   Timestamp acked_time;
96 
97   uint32_t byte_offset; /* byte offset relative to the start of the RPC */
98 
99 #ifdef GRPC_LINUX_ERRQUEUE
100   grpc_core::tcp_info info; /* tcp_info collected on sendmsg */
101 #endif                      /* GRPC_LINUX_ERRQUEUE */
102 };
103 
104 /** TracedBuffer is a class to keep track of timestamps for a specific buffer in
105  * the TCP layer. We are only tracking timestamps for Linux kernels and hence
106  * this class would only be used by Linux platforms. For all other platforms,
107  * TracedBuffer would be an empty class.
108  *
109  * The timestamps collected are according to grpc_core::Timestamps declared
110  * above.
111  *
112  * A TracedBuffer list is kept track of using the head element of the list. If
113  * the head element of the list is nullptr, then the list is empty.
114  */
115 #ifdef GRPC_LINUX_ERRQUEUE
116 class TracedBuffer {
117  public:
118   /** Use AddNewEntry function instead of using this directly. */
TracedBuffer(uint32_t seq_no,void * arg)119   TracedBuffer(uint32_t seq_no, void* arg)
120       : seq_no_(seq_no), arg_(arg), next_(nullptr) {}
121 
122   /** Add a new entry in the TracedBuffer list pointed to by head. Also saves
123    * sendmsg_time with the current timestamp. */
124   static void AddNewEntry(grpc_core::TracedBuffer** head, uint32_t seq_no,
125                           int fd, void* arg);
126 
127   /** Processes a received timestamp based on sock_extended_err and
128    * scm_timestamping structures. It will invoke the timestamps callback if the
129    * timestamp type is SCM_TSTAMP_ACK. */
130   static void ProcessTimestamp(grpc_core::TracedBuffer** head,
131                                struct sock_extended_err* serr,
132                                struct cmsghdr* opt_stats,
133                                struct scm_timestamping* tss);
134 
135   /** Cleans the list by calling the callback for each traced buffer in the list
136    * with timestamps that it has. */
137   static void Shutdown(grpc_core::TracedBuffer** head, void* remaining,
138                        grpc_error* shutdown_err);
139 
140  private:
141   uint32_t seq_no_; /* The sequence number for the last byte in the buffer */
142   void* arg_;       /* The arg to pass to timestamps_callback */
143   grpc_core::Timestamps ts_; /* The timestamps corresponding to this buffer */
144   grpc_core::TracedBuffer* next_; /* The next TracedBuffer in the list */
145 };
146 #else  /* GRPC_LINUX_ERRQUEUE */
147 class TracedBuffer {
148  public:
149   /* Dummy shutdown function */
Shutdown(grpc_core::TracedBuffer **,void *,grpc_error * shutdown_err)150   static void Shutdown(grpc_core::TracedBuffer** /*head*/, void* /*remaining*/,
151                        grpc_error* shutdown_err) {
152     GRPC_ERROR_UNREF(shutdown_err);
153   }
154 };
155 #endif /* GRPC_LINUX_ERRQUEUE */
156 
157 /** Sets the callback function to call when timestamps for a write are
158  *  collected. The callback does not own a reference to error. */
159 void grpc_tcp_set_write_timestamps_callback(void (*fn)(void*,
160                                                        grpc_core::Timestamps*,
161                                                        grpc_error* error));
162 
163 } /* namespace grpc_core */
164 
165 #endif /* GRPC_CORE_LIB_IOMGR_BUFFER_LIST_H */
166