1. 06 Feb, 2015 6 commits
    • Jon Paul Maloy's avatar
      tipc: resolve race problem at unicast message reception · c637c103
      Jon Paul Maloy authored
      
      
      TIPC handles message cardinality and sequencing at the link layer,
      before passing messages upwards to the destination sockets. During the
      upcall from link to socket no locks are held. It is therefore possible,
      and we see it happen occasionally, that messages arriving in different
      threads and delivered in sequence still bypass each other before they
      reach the destination socket. This must not happen, since it violates
      the sequentiality guarantee.
      
      We solve this by adding a new input buffer queue to the link structure.
      Arriving messages are added safely to the tail of that queue by the
      link, while the head of the queue is consumed, also safely, by the
      receiving socket. Sequentiality is secured per socket by only allowing
      buffers to be dequeued inside the socket lock. Since there may be multiple
      simultaneous readers of the queue, we use a 'filter' parameter to reduce
      the risk that they peek the same buffer from the queue, hence also
      reducing the risk of contention on the receiving socket locks.
      
      This solves the sequentiality problem, and seems to cause no measurable
      performance degradation.
      
      A nice side effect of this change is that lock handling in the functions
      tipc_rcv() and tipc_bcast_rcv() now becomes uniform, something that
      will enable future simplifications of those functions.
      Reviewed-by: Ying Xue's avatarYing Xue <ying.xue@windriver.com>
      Signed-off-by: default avatarJon Maloy <jon.maloy@ericsson.com>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      c637c103
    • Jon Paul Maloy's avatar
      tipc: use existing sk_write_queue for outgoing packet chain · 94153e36
      Jon Paul Maloy authored
      
      
      The list for outgoing traffic buffers from a socket is currently
      allocated on the stack. This forces us to initialize the queue for
      each sent message, something costing extra CPU cycles in the most
      critical data path. Later in this series we will introduce a new
      safe input buffer queue, something that would force us to initialize
      even the spinlock of the outgoing queue. A closer analysis reveals
      that the queue always is filled and emptied within the same lock_sock()
      session. It is therefore safe to use a queue aggregated in the socket
      itself for this purpose. Since there already exists a queue for this
      in struct sock, sk_write_queue, we introduce use of that queue in
      this commit.
      Reviewed-by: Ying Xue's avatarYing Xue <ying.xue@windriver.com>
      Signed-off-by: default avatarJon Maloy <jon.maloy@ericsson.com>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      94153e36
    • Jon Paul Maloy's avatar
      tipc: split up function tipc_msg_eval() · e3a77561
      Jon Paul Maloy authored
      
      
      The function tipc_msg_eval() is in reality doing two related, but
      different tasks. First it tries to find a new destination for named
      messages, in case there was no first lookup, or if the first lookup
      failed. Second, it does what its name suggests, evaluating the validity
      of the message and its destination, and returning an appropriate error
      code depending on the result.
      
      This is confusing, and in this commit we choose to break it up into two
      functions. A new function, tipc_msg_lookup_dest(), first attempts to find
      a new destination, if the message is of the right type. If this lookup
      fails, or if the message should not be subject to a second lookup, the
      already existing tipc_msg_reverse() is called. This function performs
      prepares the message for rejection, if applicable.
      Reviewed-by: Ying Xue's avatarYing Xue <ying.xue@windriver.com>
      Signed-off-by: default avatarJon Maloy <jon.maloy@ericsson.com>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      e3a77561
    • Jon Paul Maloy's avatar
      tipc: enqueue arrived buffers in socket in separate function · d570d864
      Jon Paul Maloy authored
      
      
      The code for enqueuing arriving buffers in the function tipc_sk_rcv()
      contains long code lines and currently goes to two indentation levels.
      As a cosmetic preparaton for the next commits, we break it out into
      a separate function.
      Reviewed-by: Ying Xue's avatarYing Xue <ying.xue@windriver.com>
      Signed-off-by: default avatarJon Maloy <jon.maloy@ericsson.com>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      d570d864
    • Jon Paul Maloy's avatar
      tipc: simplify message forwarding and rejection in socket layer · 1186adf7
      Jon Paul Maloy authored
      
      
      Despite recent improvements, the handling of error codes and return
      values at reception of messages in the socket layer is still confusing.
      
      In this commit, we try to make it more comprehensible. First, we
      separate between the return values coming from the functions called
      by tipc_sk_rcv(), -those are TIPC specific error codes, and the
      return values returned by tipc_sk_rcv() itself. Second, we don't
      use the returned TIPC error code as indication for whether a buffer
      should be forwarded/rejected or not; instead we use the buffer pointer
      passed along with filter_msg(). This separation is necessary because
      we sometimes want to forward messages even when there is no error
      (i.e., protocol messages and successfully secondary looked up data
      messages).
      Reviewed-by: Ying Xue's avatarYing Xue <ying.xue@windriver.com>
      Signed-off-by: default avatarJon Maloy <jon.maloy@ericsson.com>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      1186adf7
    • Jon Paul Maloy's avatar
      tipc: reduce usage of context info in socket and link · c5898636
      Jon Paul Maloy authored
      
      
      The most common usage of namespace information is when we fetch the
      own node addess from the net structure. This leads to a lot of
      passing around of a parameter of type 'struct net *' between
      functions just to make them able to obtain this address.
      
      However, in many cases this is unnecessary. The own node address
      is readily available as a member of both struct tipc_sock and
      tipc_link, and can be fetched from there instead.
      The fact that the vast majority of functions in socket.c and link.c
      anyway are maintaining a pointer to their respective base structures
      makes this option even more compelling.
      
      In this commit, we introduce the inline functions tsk_own_node()
      and link_own_node() to make it easy for functions to fetch the node
      address from those structs instead of having to pass along and
      dereference the namespace struct.
      
      In particular, we make calls to the msg_xx() functions in msg.{h,c}
      context independent by directly passing them the own node address
      as parameter when needed. Those functions should be regarded as
      leaves in the code dependency tree, and it is hence desirable to
      keep them namspace unaware.
      
      Apart from a potential positive effect on cache behavior, these
      changes make it easier to introduce the changes that will follow
      later in this series.
      Reviewed-by: Ying Xue's avatarYing Xue <ying.xue@windriver.com>
      Signed-off-by: default avatarJon Maloy <jon.maloy@ericsson.com>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      c5898636
  2. 05 Feb, 2015 34 commits