[bug report] rxrpc: Don't store the rxrpc header in the Tx queue sk_buffs

Dan Carpenter dan.carpenter at oracle.com
Wed May 16 05:11:51 EDT 2018


Hello David Howells,

The patch 5a924b8951f8: "rxrpc: Don't store the rxrpc header in the
Tx queue sk_buffs" from Sep 22, 2016, leads to the following static
checker warning:

	net/rxrpc/output.c:489 rxrpc_send_data_packet()
	error: uninitialized symbol 'ret'.

net/rxrpc/output.c
   370          if (IS_ENABLED(CONFIG_AF_RXRPC_INJECT_LOSS)) {
   371                  static int lose;
   372                  if ((lose++ & 7) == 7) {
   373                          ret = 0;
   374                          lost = true;
   375                          goto done;
   376                  }
   377          }
   378  
   379          _proto("Tx DATA %%%u { #%u }", serial, sp->hdr.seq);
   380  
   381          /* send the packet with the don't fragment bit set if we currently
   382           * think it's small enough */
   383          if (iov[1].iov_len >= call->peer->maxdata)
   384                  goto send_fragmentable;

Should we set "ret = 0" before the goto?

   385  
   386          down_read(&conn->params.local->defrag_sem);
   387          /* send the packet by UDP
   388           * - returns -EMSGSIZE if UDP would have to fragment the packet
   389           *   to go out of the interface
   390           *   - in which case, we'll have processed the ICMP error
   391           *     message and update the peer record
   392           */
   393          ret = kernel_sendmsg(conn->params.local->socket, &msg, iov, 2, len);
   394          conn->params.peer->last_tx_at = ktime_get_real();
   395  
   396          up_read(&conn->params.local->defrag_sem);
   397          if (ret < 0)
   398                  trace_rxrpc_tx_fail(call->debug_id, serial, ret,
   399                                      rxrpc_tx_fail_call_data_nofrag);
   400          if (ret == -EMSGSIZE)
   401                  goto send_fragmentable;
   402  
   403  done:
   404          trace_rxrpc_tx_data(call, sp->hdr.seq, serial, whdr.flags,
   405                              retrans, lost);
   406          if (ret >= 0) {
   407                  ktime_t now = ktime_get_real();
   408                  skb->tstamp = now;
   409                  smp_wmb();
   410                  sp->hdr.serial = serial;
   411                  if (whdr.flags & RXRPC_REQUEST_ACK) {
   412                          call->peer->rtt_last_req = now;
   413                          trace_rxrpc_rtt_tx(call, rxrpc_rtt_tx_data, serial);
   414                          if (call->peer->rtt_usage > 1) {
   415                                  unsigned long nowj = jiffies, ack_lost_at;
   416  
   417                                  ack_lost_at = nsecs_to_jiffies(2 * call->peer->rtt);
   418                                  if (ack_lost_at < 1)
   419                                          ack_lost_at = 1;
   420  
   421                                  ack_lost_at += nowj;
   422                                  WRITE_ONCE(call->ack_lost_at, ack_lost_at);
   423                                  rxrpc_reduce_call_timer(call, ack_lost_at, nowj,
   424                                                          rxrpc_timer_set_for_lost_ack);
   425                          }
   426                  }
   427  
   428                  if (sp->hdr.seq == 1 &&
   429                      !test_and_set_bit(RXRPC_CALL_BEGAN_RX_TIMER,
   430                                        &call->flags)) {
   431                          unsigned long nowj = jiffies, expect_rx_by;
   432  
   433                          expect_rx_by = nowj + call->next_rx_timo;
   434                          WRITE_ONCE(call->expect_rx_by, expect_rx_by);
   435                          rxrpc_reduce_call_timer(call, expect_rx_by, nowj,
   436                                                  rxrpc_timer_set_for_normal);
   437                  }
   438          }
   439  
   440          rxrpc_set_keepalive(call);
   441  
   442          _leave(" = %d [%u]", ret, call->peer->maxdata);
   443          return ret;
   444  
   445  send_fragmentable:
   446          /* attempt to send this message with fragmentation enabled */
   447          _debug("send fragment");
   448  
   449          down_write(&conn->params.local->defrag_sem);
   450  
   451          switch (conn->params.local->srx.transport.family) {
   452          case AF_INET:
   453                  opt = IP_PMTUDISC_DONT;
   454                  ret = kernel_setsockopt(conn->params.local->socket,
   455                                          SOL_IP, IP_MTU_DISCOVER,
   456                                          (char *)&opt, sizeof(opt));
   457                  if (ret == 0) {
   458                          ret = kernel_sendmsg(conn->params.local->socket, &msg,
   459                                               iov, 2, len);
   460                          conn->params.peer->last_tx_at = ktime_get_real();
   461  
   462                          opt = IP_PMTUDISC_DO;
   463                          kernel_setsockopt(conn->params.local->socket, SOL_IP,
   464                                            IP_MTU_DISCOVER,
   465                                            (char *)&opt, sizeof(opt));
   466                  }
   467                  break;
   468  
   469  #ifdef CONFIG_AF_RXRPC_IPV6
   470          case AF_INET6:
   471                  opt = IPV6_PMTUDISC_DONT;
   472                  ret = kernel_setsockopt(conn->params.local->socket,
   473                                          SOL_IPV6, IPV6_MTU_DISCOVER,
   474                                          (char *)&opt, sizeof(opt));
   475                  if (ret == 0) {
   476                          ret = kernel_sendmsg(conn->params.local->socket, &msg,
   477                                               iov, 2, len);
   478                          conn->params.peer->last_tx_at = ktime_get_real();
   479  
   480                          opt = IPV6_PMTUDISC_DO;
   481                          kernel_setsockopt(conn->params.local->socket,
   482                                            SOL_IPV6, IPV6_MTU_DISCOVER,
   483                                            (char *)&opt, sizeof(opt));
   484                  }
   485                  break;
   486  #endif
   487          }
   488  
   489          if (ret < 0)
   490                  trace_rxrpc_tx_fail(call->debug_id, serial, ret,
   491                                      rxrpc_tx_fail_call_data_frag);
   492  
   493          up_write(&conn->params.local->defrag_sem);
   494          goto done;
   495  }

regards,
dan carpenter



More information about the linux-afs mailing list