Commit e74a386d authored by Jon Paul Maloy's avatar Jon Paul Maloy Committed by David S. Miller

tipc: remove pre-allocated message header in link struct

Until now, we have kept a pre-allocated protocol message header
aggregated into struct tipc_link. Apart from adding unnecessary
footprint to the link instances, this requires extra code both to
initialize and re-initialize it.

We now remove this sub-optimization. This change also makes it
possible to clean up the function tipc_build_proto_msg() and remove
a couple of small functions that were accessing the mentioned header.
In particular, we can replace all occurrences of the local function
call link_own_addr(link) with the generic tipc_own_addr(net).
Acked-by: default 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>
parent 34f65dbb
...@@ -412,11 +412,6 @@ int tipc_bcast_init(struct net *net) ...@@ -412,11 +412,6 @@ int tipc_bcast_init(struct net *net)
return -ENOMEM; return -ENOMEM;
} }
void tipc_bcast_reinit(struct net *net)
{
tipc_link_reinit(tipc_bc_sndlink(net), tipc_own_addr(net));
}
void tipc_bcast_stop(struct net *net) void tipc_bcast_stop(struct net *net)
{ {
struct tipc_net *tn = net_generic(net, tipc_net_id); struct tipc_net *tn = net_generic(net, tipc_net_id);
......
...@@ -46,7 +46,6 @@ struct tipc_node_map; ...@@ -46,7 +46,6 @@ struct tipc_node_map;
extern const char tipc_bclink_name[]; extern const char tipc_bclink_name[];
int tipc_bcast_init(struct net *net); int tipc_bcast_init(struct net *net);
void tipc_bcast_reinit(struct net *net);
void tipc_bcast_stop(struct net *net); void tipc_bcast_stop(struct net *net);
void tipc_bcast_add_peer(struct net *net, struct tipc_link *l, void tipc_bcast_add_peer(struct net *net, struct tipc_link *l,
struct sk_buff_head *xmitq); struct sk_buff_head *xmitq);
......
/* /*
* net/tipc/link.c: TIPC link code * net/tipc/link.c: TIPC link code
* *
* Copyright (c) 1996-2007, 2012-2015, Ericsson AB * Copyright (c) 1996-2007, 2012-2016, Ericsson AB
* Copyright (c) 2004-2007, 2010-2013, Wind River Systems * Copyright (c) 2004-2007, 2010-2013, Wind River Systems
* All rights reserved. * All rights reserved.
* *
...@@ -127,6 +127,7 @@ struct tipc_link { ...@@ -127,6 +127,7 @@ struct tipc_link {
/* Management and link supervision data */ /* Management and link supervision data */
u32 peer_session; u32 peer_session;
u32 session;
u32 peer_bearer_id; u32 peer_bearer_id;
u32 bearer_id; u32 bearer_id;
u32 tolerance; u32 tolerance;
...@@ -136,11 +137,7 @@ struct tipc_link { ...@@ -136,11 +137,7 @@ struct tipc_link {
u16 peer_caps; u16 peer_caps;
bool active; bool active;
u32 silent_intv_cnt; u32 silent_intv_cnt;
struct { char if_name[TIPC_MAX_IF_NAME];
unchar hdr[INT_H_SIZE];
unchar body[TIPC_MAX_IF_NAME];
} proto_msg;
struct tipc_msg *pmsg;
u32 priority; u32 priority;
char net_plane; char net_plane;
...@@ -215,10 +212,11 @@ enum { ...@@ -215,10 +212,11 @@ enum {
* Interval between NACKs when packets arrive out of order * Interval between NACKs when packets arrive out of order
*/ */
#define TIPC_NACK_INTV (TIPC_MIN_LINK_WIN * 2) #define TIPC_NACK_INTV (TIPC_MIN_LINK_WIN * 2)
/*
* Out-of-range value for link session numbers /* Wildcard value for link session numbers. When it is known that
* peer endpoint is down, any session number must be accepted.
*/ */
#define WILDCARD_SESSION 0x10000 #define ANY_SESSION 0x10000
/* Link FSM states: /* Link FSM states:
*/ */
...@@ -398,16 +396,6 @@ char *tipc_link_name(struct tipc_link *l) ...@@ -398,16 +396,6 @@ char *tipc_link_name(struct tipc_link *l)
return l->name; return l->name;
} }
static u32 link_own_addr(struct tipc_link *l)
{
return msg_prevnode(l->pmsg);
}
void tipc_link_reinit(struct tipc_link *l, u32 addr)
{
msg_set_prevnode(l->pmsg, addr);
}
/** /**
* tipc_link_create - create a new link * tipc_link_create - create a new link
* @n: pointer to associated node * @n: pointer to associated node
...@@ -441,29 +429,22 @@ bool tipc_link_create(struct net *net, char *if_name, int bearer_id, ...@@ -441,29 +429,22 @@ bool tipc_link_create(struct net *net, char *if_name, int bearer_id,
struct tipc_link **link) struct tipc_link **link)
{ {
struct tipc_link *l; struct tipc_link *l;
struct tipc_msg *hdr;
l = kzalloc(sizeof(*l), GFP_ATOMIC); l = kzalloc(sizeof(*l), GFP_ATOMIC);
if (!l) if (!l)
return false; return false;
*link = l; *link = l;
l->pmsg = (struct tipc_msg *)&l->proto_msg; l->session = session;
hdr = l->pmsg;
tipc_msg_init(ownnode, hdr, LINK_PROTOCOL, RESET_MSG, INT_H_SIZE, peer);
msg_set_size(hdr, sizeof(l->proto_msg));
msg_set_session(hdr, session);
msg_set_bearer_id(hdr, l->bearer_id);
/* Note: peer i/f name is completed by reset/activate message */ /* Note: peer i/f name is completed by reset/activate message */
sprintf(l->name, "%u.%u.%u:%s-%u.%u.%u:unknown", sprintf(l->name, "%u.%u.%u:%s-%u.%u.%u:unknown",
tipc_zone(ownnode), tipc_cluster(ownnode), tipc_node(ownnode), tipc_zone(ownnode), tipc_cluster(ownnode), tipc_node(ownnode),
if_name, tipc_zone(peer), tipc_cluster(peer), tipc_node(peer)); if_name, tipc_zone(peer), tipc_cluster(peer), tipc_node(peer));
strcpy((char *)msg_data(hdr), if_name); strcpy(l->if_name, if_name);
l->addr = peer; l->addr = peer;
l->peer_caps = peer_caps; l->peer_caps = peer_caps;
l->net = net; l->net = net;
l->peer_session = WILDCARD_SESSION; l->peer_session = ANY_SESSION;
l->bearer_id = bearer_id; l->bearer_id = bearer_id;
l->tolerance = tolerance; l->tolerance = tolerance;
l->net_plane = net_plane; l->net_plane = net_plane;
...@@ -790,7 +771,7 @@ static int link_schedule_user(struct tipc_link *link, struct sk_buff_head *list) ...@@ -790,7 +771,7 @@ static int link_schedule_user(struct tipc_link *link, struct sk_buff_head *list)
struct tipc_msg *msg = buf_msg(skb_peek(list)); struct tipc_msg *msg = buf_msg(skb_peek(list));
int imp = msg_importance(msg); int imp = msg_importance(msg);
u32 oport = msg_origport(msg); u32 oport = msg_origport(msg);
u32 addr = link_own_addr(link); u32 addr = tipc_own_addr(link->net);
struct sk_buff *skb; struct sk_buff *skb;
/* This really cannot happen... */ /* This really cannot happen... */
...@@ -839,16 +820,9 @@ void link_prepare_wakeup(struct tipc_link *l) ...@@ -839,16 +820,9 @@ void link_prepare_wakeup(struct tipc_link *l)
void tipc_link_reset(struct tipc_link *l) void tipc_link_reset(struct tipc_link *l)
{ {
/* Link is down, accept any session */ l->peer_session = ANY_SESSION;
l->peer_session = WILDCARD_SESSION; l->session++;
/* If peer is up, it only accepts an incremented session number */
msg_set_session(l->pmsg, msg_session(l->pmsg) + 1);
/* Prepare for renewed mtu size negotiation */
l->mtu = l->advertised_mtu; l->mtu = l->advertised_mtu;
/* Clean up all queues and counters: */
__skb_queue_purge(&l->transmq); __skb_queue_purge(&l->transmq);
__skb_queue_purge(&l->deferdq); __skb_queue_purge(&l->deferdq);
skb_queue_splice_init(&l->wakeupq, l->inputq); skb_queue_splice_init(&l->wakeupq, l->inputq);
...@@ -1156,7 +1130,7 @@ int tipc_link_build_ack_msg(struct tipc_link *l, struct sk_buff_head *xmitq) ...@@ -1156,7 +1130,7 @@ int tipc_link_build_ack_msg(struct tipc_link *l, struct sk_buff_head *xmitq)
/* Broadcast ACK must be sent via a unicast link => defer to caller */ /* Broadcast ACK must be sent via a unicast link => defer to caller */
if (link_is_bc_rcvlink(l)) { if (link_is_bc_rcvlink(l)) {
if (((l->rcv_nxt ^ link_own_addr(l)) & 0xf) != 0xf) if (((l->rcv_nxt ^ tipc_own_addr(l->net)) & 0xf) != 0xf)
return 0; return 0;
l->rcv_unacked = 0; l->rcv_unacked = 0;
return TIPC_LINK_SND_BC_ACK; return TIPC_LINK_SND_BC_ACK;
...@@ -1268,15 +1242,30 @@ static void tipc_link_build_proto_msg(struct tipc_link *l, int mtyp, bool probe, ...@@ -1268,15 +1242,30 @@ static void tipc_link_build_proto_msg(struct tipc_link *l, int mtyp, bool probe,
u16 rcvgap, int tolerance, int priority, u16 rcvgap, int tolerance, int priority,
struct sk_buff_head *xmitq) struct sk_buff_head *xmitq)
{ {
struct sk_buff *skb = NULL; struct sk_buff *skb;
struct tipc_msg *hdr = l->pmsg; struct tipc_msg *hdr;
struct sk_buff_head *dfq = &l->deferdq;
bool node_up = link_is_up(l->bc_rcvlink); bool node_up = link_is_up(l->bc_rcvlink);
/* Don't send protocol message during reset or link failover */ /* Don't send protocol message during reset or link failover */
if (tipc_link_is_blocked(l)) if (tipc_link_is_blocked(l))
return; return;
msg_set_type(hdr, mtyp); if (!tipc_link_is_up(l) && (mtyp == STATE_MSG))
return;
if (!skb_queue_empty(dfq))
rcvgap = buf_seqno(skb_peek(dfq)) - l->rcv_nxt;
skb = tipc_msg_create(LINK_PROTOCOL, mtyp, INT_H_SIZE,
TIPC_MAX_IF_NAME, l->addr,
tipc_own_addr(l->net), 0, 0, 0);
if (!skb)
return;
hdr = buf_msg(skb);
msg_set_session(hdr, l->session);
msg_set_bearer_id(hdr, l->bearer_id);
msg_set_net_plane(hdr, l->net_plane); msg_set_net_plane(hdr, l->net_plane);
msg_set_next_sent(hdr, l->snd_nxt); msg_set_next_sent(hdr, l->snd_nxt);
msg_set_ack(hdr, l->rcv_nxt - 1); msg_set_ack(hdr, l->rcv_nxt - 1);
...@@ -1286,36 +1275,23 @@ static void tipc_link_build_proto_msg(struct tipc_link *l, int mtyp, bool probe, ...@@ -1286,36 +1275,23 @@ static void tipc_link_build_proto_msg(struct tipc_link *l, int mtyp, bool probe,
msg_set_linkprio(hdr, priority); msg_set_linkprio(hdr, priority);
msg_set_redundant_link(hdr, node_up); msg_set_redundant_link(hdr, node_up);
msg_set_seq_gap(hdr, 0); msg_set_seq_gap(hdr, 0);
/* Compatibility: created msg must not be in sequence with pkt flow */
msg_set_seqno(hdr, l->snd_nxt + U16_MAX / 2); msg_set_seqno(hdr, l->snd_nxt + U16_MAX / 2);
if (mtyp == STATE_MSG) { if (mtyp == STATE_MSG) {
if (!tipc_link_is_up(l)) msg_set_seq_gap(hdr, rcvgap);
return; msg_set_size(hdr, INT_H_SIZE);
/* Override rcvgap if there are packets in deferred queue */
if (!skb_queue_empty(&l->deferdq))
rcvgap = buf_seqno(skb_peek(&l->deferdq)) - l->rcv_nxt;
if (rcvgap) {
msg_set_seq_gap(hdr, rcvgap);
l->stats.sent_nacks++;
}
msg_set_probe(hdr, probe); msg_set_probe(hdr, probe);
if (probe)
l->stats.sent_probes++;
l->stats.sent_states++; l->stats.sent_states++;
l->rcv_unacked = 0; l->rcv_unacked = 0;
} else { } else {
/* RESET_MSG or ACTIVATE_MSG */ /* RESET_MSG or ACTIVATE_MSG */
msg_set_max_pkt(hdr, l->advertised_mtu); msg_set_max_pkt(hdr, l->advertised_mtu);
msg_set_ack(hdr, l->rcv_nxt - 1); strcpy(msg_data(hdr), l->if_name);
msg_set_next_sent(hdr, 1);
} }
skb = tipc_buf_acquire(msg_size(hdr)); if (probe)
if (!skb) l->stats.sent_probes++;
return; if (rcvgap)
skb_copy_to_linear_data(skb, hdr, msg_size(hdr)); l->stats.sent_nacks++;
skb->priority = TC_PRIO_CONTROL; skb->priority = TC_PRIO_CONTROL;
__skb_queue_tail(xmitq, skb); __skb_queue_tail(xmitq, skb);
} }
...@@ -1340,7 +1316,7 @@ void tipc_link_tnl_prepare(struct tipc_link *l, struct tipc_link *tnl, ...@@ -1340,7 +1316,7 @@ void tipc_link_tnl_prepare(struct tipc_link *l, struct tipc_link *tnl,
/* At least one packet required for safe algorithm => add dummy */ /* At least one packet required for safe algorithm => add dummy */
skb = tipc_msg_create(TIPC_LOW_IMPORTANCE, TIPC_DIRECT_MSG, skb = tipc_msg_create(TIPC_LOW_IMPORTANCE, TIPC_DIRECT_MSG,
BASIC_H_SIZE, 0, l->addr, link_own_addr(l), BASIC_H_SIZE, 0, l->addr, tipc_own_addr(l->net),
0, 0, TIPC_ERR_NO_PORT); 0, 0, TIPC_ERR_NO_PORT);
if (!skb) { if (!skb) {
pr_warn("%sunable to create tunnel packet\n", link_co_err); pr_warn("%sunable to create tunnel packet\n", link_co_err);
...@@ -1351,7 +1327,7 @@ void tipc_link_tnl_prepare(struct tipc_link *l, struct tipc_link *tnl, ...@@ -1351,7 +1327,7 @@ void tipc_link_tnl_prepare(struct tipc_link *l, struct tipc_link *tnl,
__skb_queue_purge(&tmpxq); __skb_queue_purge(&tmpxq);
/* Initialize reusable tunnel packet header */ /* Initialize reusable tunnel packet header */
tipc_msg_init(link_own_addr(l), &tnlhdr, TUNNEL_PROTOCOL, tipc_msg_init(tipc_own_addr(l->net), &tnlhdr, TUNNEL_PROTOCOL,
mtyp, INT_H_SIZE, l->addr); mtyp, INT_H_SIZE, l->addr);
pktcnt = skb_queue_len(&l->transmq) + skb_queue_len(&l->backlogq); pktcnt = skb_queue_len(&l->transmq) + skb_queue_len(&l->backlogq);
msg_set_msgcnt(&tnlhdr, pktcnt); msg_set_msgcnt(&tnlhdr, pktcnt);
...@@ -1410,7 +1386,7 @@ static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb, ...@@ -1410,7 +1386,7 @@ static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb,
if (tipc_link_is_blocked(l) || !xmitq) if (tipc_link_is_blocked(l) || !xmitq)
goto exit; goto exit;
if (link_own_addr(l) > msg_prevnode(hdr)) if (tipc_own_addr(l->net) > msg_prevnode(hdr))
l->net_plane = msg_net_plane(hdr); l->net_plane = msg_net_plane(hdr);
switch (mtyp) { switch (mtyp) {
...@@ -1418,7 +1394,7 @@ static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb, ...@@ -1418,7 +1394,7 @@ static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb,
/* Ignore duplicate RESET with old session number */ /* Ignore duplicate RESET with old session number */
if ((less_eq(msg_session(hdr), l->peer_session)) && if ((less_eq(msg_session(hdr), l->peer_session)) &&
(l->peer_session != WILDCARD_SESSION)) (l->peer_session != ANY_SESSION))
break; break;
/* fall thru' */ /* fall thru' */
...@@ -1515,7 +1491,7 @@ static bool tipc_link_build_bc_proto_msg(struct tipc_link *l, bool bcast, ...@@ -1515,7 +1491,7 @@ static bool tipc_link_build_bc_proto_msg(struct tipc_link *l, bool bcast,
u16 gap_to = peers_snd_nxt - 1; u16 gap_to = peers_snd_nxt - 1;
skb = tipc_msg_create(BCAST_PROTOCOL, STATE_MSG, INT_H_SIZE, skb = tipc_msg_create(BCAST_PROTOCOL, STATE_MSG, INT_H_SIZE,
0, l->addr, link_own_addr(l), 0, 0, 0); 0, l->addr, tipc_own_addr(l->net), 0, 0, 0);
if (!skb) if (!skb)
return false; return false;
hdr = buf_msg(skb); hdr = buf_msg(skb);
...@@ -1670,7 +1646,7 @@ int tipc_link_bc_nack_rcv(struct tipc_link *l, struct sk_buff *skb, ...@@ -1670,7 +1646,7 @@ int tipc_link_bc_nack_rcv(struct tipc_link *l, struct sk_buff *skb,
if (mtyp != STATE_MSG) if (mtyp != STATE_MSG)
return 0; return 0;
if (dnode == link_own_addr(l)) { if (dnode == tipc_own_addr(l->net)) {
tipc_link_bc_ack_rcv(l, acked, xmitq); tipc_link_bc_ack_rcv(l, acked, xmitq);
rc = tipc_link_retrans(l->bc_sndlink, from, to, xmitq); rc = tipc_link_retrans(l->bc_sndlink, from, to, xmitq);
l->stats.recv_nacks++; l->stats.recv_nacks++;
......
...@@ -86,7 +86,6 @@ bool tipc_link_bc_create(struct net *net, u32 ownnode, u32 peer, ...@@ -86,7 +86,6 @@ bool tipc_link_bc_create(struct net *net, u32 ownnode, u32 peer,
struct sk_buff_head *namedq, struct sk_buff_head *namedq,
struct tipc_link *bc_sndlink, struct tipc_link *bc_sndlink,
struct tipc_link **link); struct tipc_link **link);
void tipc_link_reinit(struct tipc_link *l, u32 addr);
void tipc_link_tnl_prepare(struct tipc_link *l, struct tipc_link *tnl, void tipc_link_tnl_prepare(struct tipc_link *l, struct tipc_link *tnl,
int mtyp, struct sk_buff_head *xmitq); int mtyp, struct sk_buff_head *xmitq);
void tipc_link_build_reset_msg(struct tipc_link *l, struct sk_buff_head *xmitq); void tipc_link_build_reset_msg(struct tipc_link *l, struct sk_buff_head *xmitq);
......
...@@ -116,7 +116,6 @@ int tipc_net_start(struct net *net, u32 addr) ...@@ -116,7 +116,6 @@ int tipc_net_start(struct net *net, u32 addr)
tn->own_addr = addr; tn->own_addr = addr;
tipc_named_reinit(net); tipc_named_reinit(net);
tipc_sk_reinit(net); tipc_sk_reinit(net);
tipc_bcast_reinit(net);
tipc_nametbl_publish(net, TIPC_CFG_SRV, tn->own_addr, tn->own_addr, tipc_nametbl_publish(net, TIPC_CFG_SRV, tn->own_addr, tn->own_addr,
TIPC_ZONE_SCOPE, 0, tn->own_addr); TIPC_ZONE_SCOPE, 0, tn->own_addr);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment