summaryrefslogtreecommitdiffstats
path: root/net/rds/recv.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/rds/recv.c')
-rw-r--r--net/rds/recv.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/net/rds/recv.c b/net/rds/recv.c
index cbfabdf3ff48..9d0666e5fe35 100644
--- a/net/rds/recv.c
+++ b/net/rds/recv.c
@@ -120,6 +120,36 @@ static void rds_recv_rcvbuf_delta(struct rds_sock *rs, struct sock *sk,
120 /* do nothing if no change in cong state */ 120 /* do nothing if no change in cong state */
121} 121}
122 122
123static void rds_conn_peer_gen_update(struct rds_connection *conn,
124 u32 peer_gen_num)
125{
126 int i;
127 struct rds_message *rm, *tmp;
128 unsigned long flags;
129
130 WARN_ON(conn->c_trans->t_type != RDS_TRANS_TCP);
131 if (peer_gen_num != 0) {
132 if (conn->c_peer_gen_num != 0 &&
133 peer_gen_num != conn->c_peer_gen_num) {
134 for (i = 0; i < RDS_MPATH_WORKERS; i++) {
135 struct rds_conn_path *cp;
136
137 cp = &conn->c_path[i];
138 spin_lock_irqsave(&cp->cp_lock, flags);
139 cp->cp_next_tx_seq = 1;
140 cp->cp_next_rx_seq = 0;
141 list_for_each_entry_safe(rm, tmp,
142 &cp->cp_retrans,
143 m_conn_item) {
144 set_bit(RDS_MSG_FLUSH, &rm->m_flags);
145 }
146 spin_unlock_irqrestore(&cp->cp_lock, flags);
147 }
148 }
149 conn->c_peer_gen_num = peer_gen_num;
150 }
151}
152
123/* 153/*
124 * Process all extension headers that come with this message. 154 * Process all extension headers that come with this message.
125 */ 155 */
@@ -163,7 +193,9 @@ static void rds_recv_hs_exthdrs(struct rds_header *hdr,
163 union { 193 union {
164 struct rds_ext_header_version version; 194 struct rds_ext_header_version version;
165 u16 rds_npaths; 195 u16 rds_npaths;
196 u32 rds_gen_num;
166 } buffer; 197 } buffer;
198 u32 new_peer_gen_num = 0;
167 199
168 while (1) { 200 while (1) {
169 len = sizeof(buffer); 201 len = sizeof(buffer);
@@ -176,6 +208,9 @@ static void rds_recv_hs_exthdrs(struct rds_header *hdr,
176 conn->c_npaths = min_t(int, RDS_MPATH_WORKERS, 208 conn->c_npaths = min_t(int, RDS_MPATH_WORKERS,
177 buffer.rds_npaths); 209 buffer.rds_npaths);
178 break; 210 break;
211 case RDS_EXTHDR_GEN_NUM:
212 new_peer_gen_num = buffer.rds_gen_num;
213 break;
179 default: 214 default:
180 pr_warn_ratelimited("ignoring unknown exthdr type " 215 pr_warn_ratelimited("ignoring unknown exthdr type "
181 "0x%x\n", type); 216 "0x%x\n", type);
@@ -183,6 +218,7 @@ static void rds_recv_hs_exthdrs(struct rds_header *hdr,
183 } 218 }
184 /* if RDS_EXTHDR_NPATHS was not found, default to a single-path */ 219 /* if RDS_EXTHDR_NPATHS was not found, default to a single-path */
185 conn->c_npaths = max_t(int, conn->c_npaths, 1); 220 conn->c_npaths = max_t(int, conn->c_npaths, 1);
221 rds_conn_peer_gen_update(conn, new_peer_gen_num);
186} 222}
187 223
188/* rds_start_mprds() will synchronously start multiple paths when appropriate. 224/* rds_start_mprds() will synchronously start multiple paths when appropriate.