tipc: avoid to asynchronously reset all links
Postpone the actions of resetting all links until after bclink lock is released, avoiding to asynchronously reset all links. Signed-off-by: Ying Xue <ying.xue@windriver.com> Reviewed-by: Erik Hugne <erik.hugne@ericsson.com> Reviewed-by: Jon Maloy <jon.maloy@ericsson.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
eb8b00f5f2
commit
3f5a12bd9f
|
@ -87,6 +87,7 @@ struct tipc_bcbearer {
|
||||||
* @lock: spinlock governing access to structure
|
* @lock: spinlock governing access to structure
|
||||||
* @link: (non-standard) broadcast link structure
|
* @link: (non-standard) broadcast link structure
|
||||||
* @node: (non-standard) node structure representing b'cast link's peer node
|
* @node: (non-standard) node structure representing b'cast link's peer node
|
||||||
|
* @flags: represent bclink states
|
||||||
* @bcast_nodes: map of broadcast-capable nodes
|
* @bcast_nodes: map of broadcast-capable nodes
|
||||||
* @retransmit_to: node that most recently requested a retransmit
|
* @retransmit_to: node that most recently requested a retransmit
|
||||||
*
|
*
|
||||||
|
@ -96,6 +97,7 @@ struct tipc_bclink {
|
||||||
spinlock_t lock;
|
spinlock_t lock;
|
||||||
struct tipc_link link;
|
struct tipc_link link;
|
||||||
struct tipc_node node;
|
struct tipc_node node;
|
||||||
|
unsigned int flags;
|
||||||
struct tipc_node_map bcast_nodes;
|
struct tipc_node_map bcast_nodes;
|
||||||
struct tipc_node *retransmit_to;
|
struct tipc_node *retransmit_to;
|
||||||
};
|
};
|
||||||
|
@ -119,7 +121,26 @@ static void tipc_bclink_lock(void)
|
||||||
|
|
||||||
static void tipc_bclink_unlock(void)
|
static void tipc_bclink_unlock(void)
|
||||||
{
|
{
|
||||||
|
struct tipc_node *node = NULL;
|
||||||
|
|
||||||
|
if (likely(!bclink->flags)) {
|
||||||
spin_unlock_bh(&bclink->lock);
|
spin_unlock_bh(&bclink->lock);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bclink->flags & TIPC_BCLINK_RESET) {
|
||||||
|
bclink->flags &= ~TIPC_BCLINK_RESET;
|
||||||
|
node = tipc_bclink_retransmit_to();
|
||||||
|
}
|
||||||
|
spin_unlock_bh(&bclink->lock);
|
||||||
|
|
||||||
|
if (node)
|
||||||
|
tipc_link_reset_all(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tipc_bclink_set_flags(unsigned int flags)
|
||||||
|
{
|
||||||
|
bclink->flags |= flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 bcbuf_acks(struct sk_buff *buf)
|
static u32 bcbuf_acks(struct sk_buff *buf)
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
|
|
||||||
#define MAX_NODES 4096
|
#define MAX_NODES 4096
|
||||||
#define WSIZE 32
|
#define WSIZE 32
|
||||||
|
#define TIPC_BCLINK_RESET 1
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct tipc_node_map - set of node identifiers
|
* struct tipc_node_map - set of node identifiers
|
||||||
|
@ -83,6 +84,7 @@ void tipc_port_list_free(struct tipc_port_list *pl_ptr);
|
||||||
|
|
||||||
int tipc_bclink_init(void);
|
int tipc_bclink_init(void);
|
||||||
void tipc_bclink_stop(void);
|
void tipc_bclink_stop(void);
|
||||||
|
void tipc_bclink_set_flags(unsigned int flags);
|
||||||
void tipc_bclink_add_node(u32 addr);
|
void tipc_bclink_add_node(u32 addr);
|
||||||
void tipc_bclink_remove_node(u32 addr);
|
void tipc_bclink_remove_node(u32 addr);
|
||||||
struct tipc_node *tipc_bclink_retransmit_to(void);
|
struct tipc_node *tipc_bclink_retransmit_to(void);
|
||||||
|
|
|
@ -1259,29 +1259,24 @@ void tipc_link_push_queue(struct tipc_link *l_ptr)
|
||||||
} while (!res);
|
} while (!res);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void link_reset_all(unsigned long addr)
|
void tipc_link_reset_all(struct tipc_node *node)
|
||||||
{
|
{
|
||||||
struct tipc_node *n_ptr;
|
|
||||||
char addr_string[16];
|
char addr_string[16];
|
||||||
u32 i;
|
u32 i;
|
||||||
|
|
||||||
n_ptr = tipc_node_find((u32)addr);
|
tipc_node_lock(node);
|
||||||
if (!n_ptr)
|
|
||||||
return; /* node no longer exists */
|
|
||||||
|
|
||||||
tipc_node_lock(n_ptr);
|
|
||||||
|
|
||||||
pr_warn("Resetting all links to %s\n",
|
pr_warn("Resetting all links to %s\n",
|
||||||
tipc_addr_string_fill(addr_string, n_ptr->addr));
|
tipc_addr_string_fill(addr_string, node->addr));
|
||||||
|
|
||||||
for (i = 0; i < MAX_BEARERS; i++) {
|
for (i = 0; i < MAX_BEARERS; i++) {
|
||||||
if (n_ptr->links[i]) {
|
if (node->links[i]) {
|
||||||
link_print(n_ptr->links[i], "Resetting link\n");
|
link_print(node->links[i], "Resetting link\n");
|
||||||
tipc_link_reset(n_ptr->links[i]);
|
tipc_link_reset(node->links[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tipc_node_unlock(n_ptr);
|
tipc_node_unlock(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void link_retransmit_failure(struct tipc_link *l_ptr,
|
static void link_retransmit_failure(struct tipc_link *l_ptr,
|
||||||
|
@ -1318,10 +1313,9 @@ static void link_retransmit_failure(struct tipc_link *l_ptr,
|
||||||
n_ptr->bclink.oos_state,
|
n_ptr->bclink.oos_state,
|
||||||
n_ptr->bclink.last_sent);
|
n_ptr->bclink.last_sent);
|
||||||
|
|
||||||
tipc_k_signal((Handler)link_reset_all, (unsigned long)n_ptr->addr);
|
|
||||||
|
|
||||||
tipc_node_unlock(n_ptr);
|
tipc_node_unlock(n_ptr);
|
||||||
|
|
||||||
|
tipc_bclink_set_flags(TIPC_BCLINK_RESET);
|
||||||
l_ptr->stale_count = 0;
|
l_ptr->stale_count = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -230,6 +230,7 @@ struct sk_buff *tipc_link_cmd_show_stats(const void *req_tlv_area,
|
||||||
int req_tlv_space);
|
int req_tlv_space);
|
||||||
struct sk_buff *tipc_link_cmd_reset_stats(const void *req_tlv_area,
|
struct sk_buff *tipc_link_cmd_reset_stats(const void *req_tlv_area,
|
||||||
int req_tlv_space);
|
int req_tlv_space);
|
||||||
|
void tipc_link_reset_all(struct tipc_node *node);
|
||||||
void tipc_link_reset(struct tipc_link *l_ptr);
|
void tipc_link_reset(struct tipc_link *l_ptr);
|
||||||
void tipc_link_reset_list(unsigned int bearer_id);
|
void tipc_link_reset_list(unsigned int bearer_id);
|
||||||
int tipc_link_xmit(struct sk_buff *buf, u32 dest, u32 selector);
|
int tipc_link_xmit(struct sk_buff *buf, u32 dest, u32 selector);
|
||||||
|
|
Loading…
Reference in New Issue