15 Apr, 2016

1 commit

  • Until now, the requests sent to topology server are queued
    to a workqueue by the generic server framework.
    These messages are processed by worker threads and trigger the
    registered callbacks.
    To reduce latency on uniprocessor systems, explicit rescheduling
    is performed using cond_resched() after MAX_RECV_MSG_COUNT(25)
    messages.

    This implementation on SMP systems leads to an subscriber refcnt
    error as described below:
    When a worker thread yields by calling cond_resched() in a SMP
    system, a new worker is created on another CPU to process the
    pending workitem. Sometimes the sleeping thread wakes up before
    the new thread finishes execution.
    This breaks the assumption on ordering and being single threaded.
    The fault is more frequent when MAX_RECV_MSG_COUNT is lowered.

    If the first thread was processing subscription create and the
    second thread processing close(), the close request will free
    the subscriber and the create request oops as follows:

    [31.224137] WARNING: CPU: 2 PID: 266 at include/linux/kref.h:46 tipc_subscrb_rcv_cb+0x317/0x380 [tipc]
    [31.228143] CPU: 2 PID: 266 Comm: kworker/u8:1 Not tainted 4.5.0+ #97
    [31.228377] Workqueue: tipc_rcv tipc_recv_work [tipc]
    [...]
    [31.228377] Call Trace:
    [31.228377] [] dump_stack+0x4d/0x72
    [31.228377] [] __warn+0xd1/0xf0
    [31.228377] [] warn_slowpath_null+0x1d/0x20
    [31.228377] [] tipc_subscrb_rcv_cb+0x317/0x380 [tipc]
    [31.228377] [] tipc_receive_from_sock+0xd4/0x130 [tipc]
    [31.228377] [] tipc_recv_work+0x2b/0x50 [tipc]
    [31.228377] [] process_one_work+0x145/0x3d0
    [31.246554] ---[ end trace c3882c9baa05a4fd ]---
    [31.248327] BUG: spinlock bad magic on CPU#2, kworker/u8:1/266
    [31.249119] BUG: unable to handle kernel NULL pointer dereference at 0000000000000428
    [31.249323] IP: [] spin_dump+0x5c/0xe0
    [31.249323] PGD 0
    [31.249323] Oops: 0000 [#1] SMP

    In this commit, we
    - rename tipc_conn_shutdown() to tipc_conn_release().
    - move connection release callback execution from tipc_close_conn()
    to a new function tipc_sock_release(), which is executed before
    we free the connection.
    Thus we release the subscriber during connection release procedure
    rather than connection shutdown procedure.

    Signed-off-by: Parthasarathy Bhuvaragan
    Acked-by: Ying Xue
    Signed-off-by: David S. Miller

    Parthasarathy Bhuvaragan
     

13 Jan, 2015

3 commits

  • TIPC establishes one subscriber server which allows users to subscribe
    their interesting name service status. After tipc supports namespace,
    one dedicated tipc stack instance is created for each namespace, and
    each instance can be deemed as one independent TIPC node. As a result,
    subscriber server must be built for each namespace.

    Signed-off-by: Ying Xue
    Tested-by: Tero Aho
    Reviewed-by: Jon Maloy
    Signed-off-by: David S. Miller

    Ying Xue
     
  • TIPC name table is used to store the mapping relationship between
    TIPC service name and socket port ID. When tipc supports namespace,
    it allows users to publish service names only owned by a certain
    namespace. Therefore, every namespace must have its private name
    table to prevent service names published to one namespace from being
    contaminated by other service names in another namespace. Therefore,
    The name table global variable (ie, nametbl) and its lock must be
    moved to tipc_net structure, and a parameter of namespace must be
    added for necessary functions so that they can obtain name table
    variable defined in tipc_net structure.

    Signed-off-by: Ying Xue
    Tested-by: Tero Aho
    Reviewed-by: Jon Maloy
    Signed-off-by: David S. Miller

    Ying Xue
     
  • Only the works of initializing and shutting down tipc module are done
    in core.h and core.c files, so all stuffs which are not closely
    associated with the two tasks should be moved to appropriate places.

    Signed-off-by: Ying Xue
    Tested-by: Tero Aho
    Reviewed-by: Jon Maloy
    Signed-off-by: David S. Miller

    Ying Xue
     

22 Feb, 2014

1 commit

  • When tipc module is inserted, many tipc components are initialized
    one by one. During the initialization period, if one of them is
    failed, tipc_core_stop() will be called to stop all components
    whatever corresponding components are created or not. To avoid to
    release uncreated ones, relevant components have to add necessary
    enabled flags indicating whether they are created or not.

    But in the initialization stage, if one component is unsuccessfully
    created, we will just destroy successfully created components before
    the failed component instead of all components. All enabled flags
    defined in components, in turn, become redundant. Additionally it's
    also unnecessary to identify whether table.types is NULL in
    tipc_nametbl_stop() because name stable has been definitely created
    successfully when tipc_nametbl_stop() is called.

    Cc: Jon Maloy
    Cc: Erik Hugne
    Signed-off-by: Ying Xue
    Reviewed-by: Paul Gortmaker
    Signed-off-by: David S. Miller

    Ying Xue
     

18 Jun, 2013

1 commit

  • TIPC has two internal servers, one providing a subscription
    service for topology events, and another providing the
    configuration interface. These servers have previously been running
    in BH context, accessing the TIPC-port (aka native) API directly.
    Apart from these servers, even the TIPC socket implementation is
    partially built on this API.

    As this API may simultaneously be called via different paths and in
    different contexts, a complex and costly lock policiy is required
    in order to protect TIPC internal resources.

    To eliminate the need for this complex lock policiy, we introduce
    a new, generic service API that uses kernel sockets for message
    passing instead of the native API. Once the toplogy and configuration
    servers are converted to use this new service, all code pertaining
    to the native API can be removed. This entails a significant
    reduction in code amount and complexity, and opens up for a complete
    rework of the locking policy in TIPC.

    The new service also solves another problem:

    As the current topology server works in BH context, it cannot easily
    be blocked when sending of events fails due to congestion. In such
    cases events may have to be silently dropped, something that is
    unacceptable. Therefore, the new service keeps a dedicated outbound
    queue receiving messages from BH context. Once messages are
    inserted into this queue, we will immediately schedule a work from a
    special workqueue. This way, messages/events from the topology server
    are in reality sent in process context, and the server can block
    if necessary.

    Analogously, there is a new workqueue for receiving messages. Once a
    notification about an arriving message is received in BH context, we
    schedule a work from the receive workqueue to do the job of
    receiving the message in process context.

    As both sending and receive messages are now finished in processes,
    subscribed events cannot be dropped any more.

    As of this commit, this new server infrastructure is built, but
    not actually yet called by the existing TIPC code, but since the
    conversion changes required in order to use it are significant,
    the addition is kept here as a separate commit.

    Signed-off-by: Ying Xue
    Signed-off-by: Jon Maloy
    Signed-off-by: Paul Gortmaker
    Signed-off-by: David S. Miller

    Ying Xue