* Re: [PATCH 0/4] support GMAC driver for RK3288
From: Kever Yang @ 2014-11-26 4:05 UTC (permalink / raw)
To: Roger Chen, heiko
Cc: peppe.cavallaro, netdev, linux-kernel, linux-rockchip, mark.yao,
eddie.cai
In-Reply-To: <1416906460-26078-1-git-send-email-roger.chen@rock-chips.com>
Hi Roger,
Please use the --in-reply-to option for patches other than 0/4
with the git send-email.
On 11/25/2014 05:07 PM, Roger Chen wrote:
> Roger Chen (4):
> patch1: add driver for Rockchip RK3288 SoCs integrated GMAC
> patch2: modify CRU config for Rockchip RK3288 SoCs integrated GMAC
> patch3: dts: add gmac info for rk3288
> patch4: dts: enable gmac on RK3288 evb board
>
> tested on rk3288 SDK board:
> busybox ifconfig eth0 up
> busybox ifconfig eth0 192.168.1.111
> ping 192.168.1.1
>
^ permalink raw reply
* Re: [net-next PATCH 2/5] ethernet/intel: Use eth_skb_pad helper
From: Eric Dumazet @ 2014-11-26 4:01 UTC (permalink / raw)
To: David Miller
Cc: alexander.duyck, alexander.h.duyck, netdev, jeffrey.t.kirsher
In-Reply-To: <20141125.221900.653470310152197801.davem@davemloft.net>
On Tue, 2014-11-25 at 22:19 -0500, David Miller wrote:
> From: Eric Dumazet <eric.dumazet@gmail.com>
> Date: Tue, 25 Nov 2014 17:43:05 -0800
>
> > I believe I finally have an idea why we had various + 15 in skb
> > allocations in TCP stack !
>
> It was so that you could do one level of tunneling with "for
> free". Or that is my recollection.
>
> Those + 15 existed way before any of these padto() calls even
> existed.
Well, tunneling is added in front of the packet. Thats why we use
MAX_TCP_HEADER.
The +15 is in fact because TCP stack wanted to make sure the eventual
padding (needing tailroom, not headroom) was possible...
Note that ack packets never used the +15, but other packets did.
^ permalink raw reply
* Re: [patch net-next v3 02/17] net: make vid as a parameter for ndo_fdb_add/ndo_fdb_del
From: Scott Feldman @ 2014-11-26 3:59 UTC (permalink / raw)
To: Jamal Hadi Salim
Cc: John Fastabend, Jiri Pirko, Netdev, David S. Miller,
nhorman@tuxdriver.com, Andy Gospodarek, Thomas Graf,
dborkman@redhat.com, ogerlitz@mellanox.com, jesse@nicira.com,
pshelar@nicira.com, azhou@nicira.com, ben@decadent.org.uk,
stephen@networkplumber.org, Kirsher, Jeffrey T,
vyasevic@redhat.com, Cong Wang, Eric Dumazet, Florian Fainelli,
Roopa Prabhu, John Linville
In-Reply-To: <547546C5.3060207@mojatatu.com>
On Tue, Nov 25, 2014 at 5:19 PM, Jamal Hadi Salim <jhs@mojatatu.com> wrote:
> On 11/25/14 21:36, Scott Feldman wrote:
>>
>> On Tue, Nov 25, 2014 at 6:50 AM, Jamal Hadi Salim <jhs@mojatatu.com>
>> wrote:
>>>
>>> On 11/25/14 11:30, John Fastabend wrote:
>
>
>>> Ok, guess i am gonna have to go stare at the code some more.
>>> I thought we returned one of the error codes?
>>> A bitmask would work for a single entry - because you have two
>>> options add to h/ware and/or s/ware. So response is easy to encode.
>>> But if i have 1000 and they are sparsely populated (think an indexed
>>> table and i have indices 1, 23, 45, etc), then a bitmask would be
>>> hard to use.
>>
>>
>> I'm confused by this discussion.
>
>
> This is about the policy which states "install as many as you can, dont
> worry about failures". In such a case, how do you tell user space back
> "oh, btw you know your request #1, #23, and 45 went ok, but nothing else
> worked". A simple return code wont work. You could return a code to
> say "some worked". At which case user space could dump and find out only
> #1, #23 and #45 worked.
You request for what? That's my confusion. Are you trying to install
FDB entry into both SW and HW at same time? And then do a bunch in a
batch? I'm saying use MASTER for SW and SELF for HW in two steps, if
you want FDB entry installed in both Sw and HW. Check your return
code each step. Batch all to HW first, then batch all that PASSED to
SW. I don't even know really why you're trying to install to both HW
and SW. Install it to HW and be done. fdb_dump will set HW entries
via SELF.
> Your question below is a different context; Some people may want
> the policy where whats in hardware
> a) gets to be seen in software and b) allow for destination lookup
> failures in hardware to show up in the kernel, refresh the fdb in the
> kernel via learning
> and c) whats in s.ware gets synced to hardware just because there's
> space in the hardware
> I dont want any of the above;-> Which would work if we had policy knobs.
> Learning, flooding, sync from hardware. Speaking of the last one:
> Where is my cookie Scott? I want my cookie.
Ah, Jamal, look again at patches 13-17/17 in last v3 set. That was a
big steaming snickerdoodle just for you! Now you can push policy
knobs down to port driver and or bridge to fine tune what ever you
want. You'll find knobs for learning, flooding, learning sync to hw,
etc. I thought you even ACKed some of these. a) above knob is 14/17
patch, b) above is using existing learning knob on bridge, c) above I
don't get...no point in syncing that direction.
> cheers,
> jamal
>
>
>
>> Do I have this right: You want to
>> send 1000 RTM_NEWNEIGHs to PF_BRIDGE with both NTF_MASTER and NTF_SELF
>> set such that 1000 new FBD entries are installed in both (SW) the
>> bridge's FDB and (HW) the port driver's FDB. My first confusion is
>> why do you want these FBD entries in bridge's FDB? We're offloading
>> the switching to HW so HW should be handling fwd plane. If ctrl pkt
>> make it to SW, it can learn those FDB entries;
>> no need for manual
>> install of FDB entry in SW. It seems to me you only want to use
>> NTF_SELF to install the FDB entry in HW using the port driver. And an
>> error code is returned for that install. Since there is only one
>> target (NTF_SELF) there is no need for bitmask return.
>
>
>
>
^ permalink raw reply
* [PATCH net-next 02/11] tipc: remove protocol message queue
From: Ying Xue @ 2014-11-26 3:41 UTC (permalink / raw)
To: davem
Cc: jon.maloy, Paul.Gortmaker, erik.hugne, richard.alpe, netdev,
tipc-discussion
In-Reply-To: <1416973315-6047-1-git-send-email-ying.xue@windriver.com>
TIPC protocol message queue is intended to save one protocol message
when bearer is congested so that the message stored in the queue can
be immediately transmitted when bearer congestion is released. However,
as now the protocol queue has no mission any more with the removal of
bearer congestion mechanism, it should be removed.
Signed-off-by: Ying Xue <ying.xue@windriver.com>
Reviewed-by: Jon Maloy <jon.maloy@ericsson.com>
---
net/tipc/link.c | 22 ----------------------
net/tipc/link.h | 2 --
2 files changed, 24 deletions(-)
diff --git a/net/tipc/link.c b/net/tipc/link.c
index 4738cb1..450ed0c 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -421,8 +421,6 @@ void tipc_link_purge_queues(struct tipc_link *l_ptr)
kfree_skb_list(l_ptr->oldest_deferred_in);
kfree_skb_list(l_ptr->first_out);
tipc_link_reset_fragments(l_ptr);
- kfree_skb(l_ptr->proto_msg_queue);
- l_ptr->proto_msg_queue = NULL;
}
void tipc_link_reset(struct tipc_link *l_ptr)
@@ -455,8 +453,6 @@ void tipc_link_reset(struct tipc_link *l_ptr)
/* Clean up all queues: */
link_release_outqueue(l_ptr);
- kfree_skb(l_ptr->proto_msg_queue);
- l_ptr->proto_msg_queue = NULL;
kfree_skb_list(l_ptr->oldest_deferred_in);
if (!skb_queue_empty(&l_ptr->waiting_sks)) {
skb_queue_splice_init(&l_ptr->waiting_sks, &owner->waiting_sks);
@@ -904,18 +900,6 @@ static u32 tipc_link_push_packet(struct tipc_link *l_ptr)
return 0;
}
- /* Send deferred protocol message, if any: */
- buf = l_ptr->proto_msg_queue;
- if (buf) {
- msg_set_ack(buf_msg(buf), mod(l_ptr->next_in_no - 1));
- msg_set_bcast_ack(buf_msg(buf), l_ptr->owner->bclink.last_in);
- tipc_bearer_send(l_ptr->bearer_id, buf, &l_ptr->media_addr);
- l_ptr->unacked_window = 0;
- kfree_skb(buf);
- l_ptr->proto_msg_queue = NULL;
- return 0;
- }
-
/* Send one deferred data message, if send window not full: */
buf = l_ptr->next_out;
if (buf) {
@@ -1446,12 +1430,6 @@ void tipc_link_proto_xmit(struct tipc_link *l_ptr, u32 msg_typ, int probe_msg,
u32 msg_size = sizeof(l_ptr->proto_msg);
int r_flag;
- /* Discard any previous message that was deferred due to congestion */
- if (l_ptr->proto_msg_queue) {
- kfree_skb(l_ptr->proto_msg_queue);
- l_ptr->proto_msg_queue = NULL;
- }
-
/* Don't send protocol message during link changeover */
if (l_ptr->exp_msg_count)
return;
diff --git a/net/tipc/link.h b/net/tipc/link.h
index f463e7b..fb3f99b 100644
--- a/net/tipc/link.h
+++ b/net/tipc/link.h
@@ -130,7 +130,6 @@ struct tipc_stats {
* @oldest_deferred_in: ptr to first inbound message in queue
* @newest_deferred_in: ptr to last inbound message in queue
* @unacked_window: # of inbound messages rx'd without ack'ing back to peer
- * @proto_msg_queue: ptr to (single) outbound control message
* @retransm_queue_size: number of messages to retransmit
* @retransm_queue_head: sequence number of first message to retransmit
* @next_out: ptr to first unsent outbound message in queue
@@ -191,7 +190,6 @@ struct tipc_link {
u32 unacked_window;
/* Congestion handling */
- struct sk_buff *proto_msg_queue;
u32 retransm_queue_size;
u32 retransm_queue_head;
struct sk_buff *next_out;
--
1.7.9.5
^ permalink raw reply related
* [PATCH net-next 00/11] standardize TIPC SKB queue operations
From: Ying Xue @ 2014-11-26 3:41 UTC (permalink / raw)
To: davem
Cc: jon.maloy, Paul.Gortmaker, erik.hugne, richard.alpe, netdev,
tipc-discussion
Now the following SKB queues are created and maintained within internal
TIPC stack:
- link transmission queue
- link deferred queue
- link receive queue
- socket outgoing packet chain
- name table outgoing packet chain
In order to manage above queues, TIPC stack declares a sk_buff pointer
for each queue to record its head, and directly modifies "prev" and
"next" SKB pointers of SKB structure when inserting or deleting a SKB
to or from the queue. As these operations are pretty complex, they
easily involve fatal mistakes. If these sk_buff pointers are replaced
with sk_buff_head instances as queue heads and corresponding generic
SKB list APIs are used to manage them, the entire TIPC code would
become quite clean and readable. But before make the change, we need
to clean up below redundant functionalities:
- remove node subscribe infrastructure
- remove protocol message queue
- remove retransmission queue
- clean up process of pushing packets in link layer
Ying Xue (11):
tipc: remove node subscription infrastructure
tipc: remove protocol message queue
tipc: remove retransmission queue
tipc: clean up the process of link pushing packets
tipc: eliminate two pseudo message types of BUNDLE_OPEN and
BUNDLE_CLOSED
tipc: remove unused between routine
tipc: use skb_queue_walk_safe marco to simplify link_prepare_wakeup
routine
tipc: use generic SKB list APIs to manage link transmission queue
tipc: use generic SKB list APIs to manage deferred queue of link
tipc: use generic SKB list APIs to manage link receive queue
tipc: use generic SKB list APIs to manage TIPC outgoing packet chains
net/tipc/Makefile | 4 +-
net/tipc/bcast.c | 109 +++++-----
net/tipc/bcast.h | 2 +-
net/tipc/bearer.h | 2 +-
net/tipc/core.h | 1 +
net/tipc/link.c | 514 ++++++++++++++++++++----------------------------
net/tipc/link.h | 48 ++---
net/tipc/msg.c | 125 ++++++------
net/tipc/msg.h | 16 +-
net/tipc/name_distr.c | 98 ++++++---
net/tipc/name_distr.h | 1 +
net/tipc/name_table.c | 2 +-
net/tipc/name_table.h | 6 +-
net/tipc/node.c | 10 +-
net/tipc/node.h | 12 +-
net/tipc/node_subscr.c | 96 ---------
net/tipc/node_subscr.h | 63 ------
net/tipc/socket.c | 127 ++++++------
18 files changed, 496 insertions(+), 740 deletions(-)
delete mode 100644 net/tipc/node_subscr.c
delete mode 100644 net/tipc/node_subscr.h
--
1.7.9.5
^ permalink raw reply
* [PATCH net-next 11/11] tipc: use generic SKB list APIs to manage TIPC outgoing packet chains
From: Ying Xue @ 2014-11-26 3:41 UTC (permalink / raw)
To: davem; +Cc: jon.maloy, netdev, Paul.Gortmaker, tipc-discussion
In-Reply-To: <1416973315-6047-1-git-send-email-ying.xue@windriver.com>
Use standard SKB list APIs associated with struct sk_buff_head to
manage socket outgoing packet chain and name table outgoing packet
chain, having relevant code simpler and more readable.
Signed-off-by: Ying Xue <ying.xue@windriver.com>
Reviewed-by: Jon Maloy <jon.maloy@ericsson.com>
---
net/tipc/bcast.c | 20 ++++----
net/tipc/bcast.h | 2 +-
net/tipc/link.c | 98 ++++++++++++++++++++++++--------------
net/tipc/link.h | 5 +-
net/tipc/msg.c | 74 ++++++++++++++--------------
net/tipc/msg.h | 6 +--
net/tipc/name_distr.c | 46 +++++++++---------
net/tipc/socket.c | 127 +++++++++++++++++++++++++------------------------
8 files changed, 203 insertions(+), 175 deletions(-)
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c
index 7b238b1..f0761c7 100644
--- a/net/tipc/bcast.c
+++ b/net/tipc/bcast.c
@@ -398,20 +398,20 @@ static void bclink_peek_nack(struct tipc_msg *msg)
/* tipc_bclink_xmit - broadcast buffer chain to all nodes in cluster
* and to identified node local sockets
- * @buf: chain of buffers containing message
+ * @list: chain of buffers containing message
* Consumes the buffer chain, except when returning -ELINKCONG
* Returns 0 if success, otherwise errno: -ELINKCONG,-EHOSTUNREACH,-EMSGSIZE
*/
-int tipc_bclink_xmit(struct sk_buff *buf)
+int tipc_bclink_xmit(struct sk_buff_head *list)
{
int rc = 0;
int bc = 0;
- struct sk_buff *clbuf;
+ struct sk_buff *skb;
/* Prepare clone of message for local node */
- clbuf = tipc_msg_reassemble(buf);
- if (unlikely(!clbuf)) {
- kfree_skb_list(buf);
+ skb = tipc_msg_reassemble(list);
+ if (unlikely(!skb)) {
+ __skb_queue_purge(list);
return -EHOSTUNREACH;
}
@@ -419,7 +419,7 @@ int tipc_bclink_xmit(struct sk_buff *buf)
if (likely(bclink)) {
tipc_bclink_lock();
if (likely(bclink->bcast_nodes.count)) {
- rc = __tipc_link_xmit(bcl, buf);
+ rc = __tipc_link_xmit(bcl, list);
if (likely(!rc)) {
u32 len = skb_queue_len(&bcl->outqueue);
@@ -433,13 +433,13 @@ int tipc_bclink_xmit(struct sk_buff *buf)
}
if (unlikely(!bc))
- kfree_skb_list(buf);
+ __skb_queue_purge(list);
/* Deliver message clone */
if (likely(!rc))
- tipc_sk_mcast_rcv(clbuf);
+ tipc_sk_mcast_rcv(skb);
else
- kfree_skb(clbuf);
+ kfree_skb(skb);
return rc;
}
diff --git a/net/tipc/bcast.h b/net/tipc/bcast.h
index 443de08..644d791 100644
--- a/net/tipc/bcast.h
+++ b/net/tipc/bcast.h
@@ -100,7 +100,7 @@ int tipc_bclink_reset_stats(void);
int tipc_bclink_set_queue_limits(u32 limit);
void tipc_bcbearer_sort(struct tipc_node_map *nm_ptr, u32 node, bool action);
uint tipc_bclink_get_mtu(void);
-int tipc_bclink_xmit(struct sk_buff *buf);
+int tipc_bclink_xmit(struct sk_buff_head *list);
void tipc_bclink_wakeup_users(void);
int tipc_nl_add_bc_link(struct tipc_nl_msg *msg);
diff --git a/net/tipc/link.c b/net/tipc/link.c
index 0e04508..34bf15c 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -664,9 +664,10 @@ static void link_state_event(struct tipc_link *l_ptr, unsigned int event)
* - For all other messages we discard the buffer and return -EHOSTUNREACH
* - For TIPC internal messages we also reset the link
*/
-static int tipc_link_cong(struct tipc_link *link, struct sk_buff *buf)
+static int tipc_link_cong(struct tipc_link *link, struct sk_buff_head *list)
{
- struct tipc_msg *msg = buf_msg(buf);
+ struct sk_buff *skb = skb_peek(list);
+ struct tipc_msg *msg = buf_msg(skb);
uint imp = tipc_msg_tot_importance(msg);
u32 oport = msg_tot_origport(msg);
@@ -679,28 +680,29 @@ static int tipc_link_cong(struct tipc_link *link, struct sk_buff *buf)
goto drop;
if (unlikely(msg_reroute_cnt(msg)))
goto drop;
- if (TIPC_SKB_CB(buf)->wakeup_pending)
+ if (TIPC_SKB_CB(skb)->wakeup_pending)
return -ELINKCONG;
- if (link_schedule_user(link, oport, TIPC_SKB_CB(buf)->chain_sz, imp))
+ if (link_schedule_user(link, oport, skb_queue_len(list), imp))
return -ELINKCONG;
drop:
- kfree_skb_list(buf);
+ __skb_queue_purge(list);
return -EHOSTUNREACH;
}
/**
* __tipc_link_xmit(): same as tipc_link_xmit, but destlink is known & locked
* @link: link to use
- * @skb: chain of buffers containing message
+ * @list: chain of buffers containing message
+ *
* Consumes the buffer chain, except when returning -ELINKCONG
* Returns 0 if success, otherwise errno: -ELINKCONG, -EMSGSIZE (plain socket
* user data messages) or -EHOSTUNREACH (all other messages/senders)
* Only the socket functions tipc_send_stream() and tipc_send_packet() need
* to act on the return value, since they may need to do more send attempts.
*/
-int __tipc_link_xmit(struct tipc_link *link, struct sk_buff *skb)
+int __tipc_link_xmit(struct tipc_link *link, struct sk_buff_head *list)
{
- struct tipc_msg *msg = buf_msg(skb);
+ struct tipc_msg *msg = buf_msg(skb_peek(list));
uint psz = msg_size(msg);
uint sndlim = link->queue_limit[0];
uint imp = tipc_msg_tot_importance(msg);
@@ -710,21 +712,21 @@ int __tipc_link_xmit(struct tipc_link *link, struct sk_buff *skb)
uint bc_last_in = link->owner->bclink.last_in;
struct tipc_media_addr *addr = &link->media_addr;
struct sk_buff_head *outqueue = &link->outqueue;
- struct sk_buff *next;
+ struct sk_buff *skb, *tmp;
/* Match queue limits against msg importance: */
if (unlikely(skb_queue_len(outqueue) >= link->queue_limit[imp]))
- return tipc_link_cong(link, skb);
+ return tipc_link_cong(link, list);
/* Has valid packet limit been used ? */
if (unlikely(psz > mtu)) {
- kfree_skb_list(skb);
+ __skb_queue_purge(list);
return -EMSGSIZE;
}
/* Prepare each packet for sending, and add to outqueue: */
- while (skb) {
- next = skb->next;
+ skb_queue_walk_safe(list, skb, tmp) {
+ __skb_unlink(skb, list);
msg = buf_msg(skb);
msg_set_word(msg, 2, ((ack << 16) | mod(seqno)));
msg_set_bcast_ack(msg, bc_last_in);
@@ -736,7 +738,6 @@ int __tipc_link_xmit(struct tipc_link *link, struct sk_buff *skb)
link->unacked_window = 0;
} else if (tipc_msg_bundle(outqueue, skb, mtu)) {
link->stats.sent_bundled++;
- skb = next;
continue;
} else if (tipc_msg_make_bundle(outqueue, skb, mtu,
link->addr)) {
@@ -750,22 +751,43 @@ int __tipc_link_xmit(struct tipc_link *link, struct sk_buff *skb)
link->next_out = skb;
}
seqno++;
- skb = next;
}
link->next_out_no = seqno;
return 0;
}
+static void skb2list(struct sk_buff *skb, struct sk_buff_head *list)
+{
+ __skb_queue_head_init(list);
+ __skb_queue_tail(list, skb);
+}
+
+static int __tipc_link_xmit_skb(struct tipc_link *link, struct sk_buff *skb)
+{
+ struct sk_buff_head head;
+
+ skb2list(skb, &head);
+ return __tipc_link_xmit(link, &head);
+}
+
+int tipc_link_xmit_skb(struct sk_buff *skb, u32 dnode, u32 selector)
+{
+ struct sk_buff_head head;
+
+ skb2list(skb, &head);
+ return tipc_link_xmit(&head, dnode, selector);
+}
+
/**
* tipc_link_xmit() is the general link level function for message sending
- * @buf: chain of buffers containing message
+ * @list: chain of buffers containing message
* @dsz: amount of user data to be sent
* @dnode: address of destination node
* @selector: a number used for deterministic link selection
* Consumes the buffer chain, except when returning -ELINKCONG
* Returns 0 if success, otherwise errno: -ELINKCONG,-EHOSTUNREACH,-EMSGSIZE
*/
-int tipc_link_xmit(struct sk_buff *buf, u32 dnode, u32 selector)
+int tipc_link_xmit(struct sk_buff_head *list, u32 dnode, u32 selector)
{
struct tipc_link *link = NULL;
struct tipc_node *node;
@@ -776,17 +798,22 @@ int tipc_link_xmit(struct sk_buff *buf, u32 dnode, u32 selector)
tipc_node_lock(node);
link = node->active_links[selector & 1];
if (link)
- rc = __tipc_link_xmit(link, buf);
+ rc = __tipc_link_xmit(link, list);
tipc_node_unlock(node);
}
if (link)
return rc;
- if (likely(in_own_node(dnode)))
- return tipc_sk_rcv(buf);
+ if (likely(in_own_node(dnode))) {
+ /* As a node local message chain never contains more than one
+ * buffer, we just need to dequeue one SKB buffer from the
+ * head list.
+ */
+ return tipc_sk_rcv(__skb_dequeue(list));
+ }
+ __skb_queue_purge(list);
- kfree_skb_list(buf);
return rc;
}
@@ -800,17 +827,17 @@ int tipc_link_xmit(struct sk_buff *buf, u32 dnode, u32 selector)
*/
static void tipc_link_sync_xmit(struct tipc_link *link)
{
- struct sk_buff *buf;
+ struct sk_buff *skb;
struct tipc_msg *msg;
- buf = tipc_buf_acquire(INT_H_SIZE);
- if (!buf)
+ skb = tipc_buf_acquire(INT_H_SIZE);
+ if (!skb)
return;
- msg = buf_msg(buf);
+ msg = buf_msg(skb);
tipc_msg_init(msg, BCAST_PROTOCOL, STATE_MSG, INT_H_SIZE, link->addr);
msg_set_last_bcast(msg, link->owner->bclink.acked);
- __tipc_link_xmit(link, buf);
+ __tipc_link_xmit_skb(link, skb);
}
/*
@@ -1053,8 +1080,7 @@ void tipc_rcv(struct sk_buff *skb, struct tipc_bearer *b_ptr)
u32 ackd;
u32 released;
- __skb_queue_head_init(&head);
- __skb_queue_tail(&head, skb);
+ skb2list(skb, &head);
while ((skb = __skb_dequeue(&head))) {
/* Ensure message is well-formed */
@@ -1573,7 +1599,7 @@ static void tipc_link_tunnel_xmit(struct tipc_link *l_ptr,
u32 selector)
{
struct tipc_link *tunnel;
- struct sk_buff *buf;
+ struct sk_buff *skb;
u32 length = msg_size(msg);
tunnel = l_ptr->owner->active_links[selector & 1];
@@ -1582,14 +1608,14 @@ static void tipc_link_tunnel_xmit(struct tipc_link *l_ptr,
return;
}
msg_set_size(tunnel_hdr, length + INT_H_SIZE);
- buf = tipc_buf_acquire(length + INT_H_SIZE);
- if (!buf) {
+ skb = tipc_buf_acquire(length + INT_H_SIZE);
+ if (!skb) {
pr_warn("%sunable to send tunnel msg\n", link_co_err);
return;
}
- skb_copy_to_linear_data(buf, tunnel_hdr, INT_H_SIZE);
- skb_copy_to_linear_data_offset(buf, INT_H_SIZE, msg, length);
- __tipc_link_xmit(tunnel, buf);
+ skb_copy_to_linear_data(skb, tunnel_hdr, INT_H_SIZE);
+ skb_copy_to_linear_data_offset(skb, INT_H_SIZE, msg, length);
+ __tipc_link_xmit_skb(tunnel, skb);
}
@@ -1620,7 +1646,7 @@ void tipc_link_failover_send_queue(struct tipc_link *l_ptr)
if (skb) {
skb_copy_to_linear_data(skb, &tunnel_hdr, INT_H_SIZE);
msg_set_size(&tunnel_hdr, INT_H_SIZE);
- __tipc_link_xmit(tunnel, skb);
+ __tipc_link_xmit_skb(tunnel, skb);
} else {
pr_warn("%sunable to send changeover msg\n",
link_co_err);
@@ -1691,7 +1717,7 @@ void tipc_link_dup_queue_xmit(struct tipc_link *l_ptr,
skb_copy_to_linear_data(outskb, &tunnel_hdr, INT_H_SIZE);
skb_copy_to_linear_data_offset(outskb, INT_H_SIZE, skb->data,
length);
- __tipc_link_xmit(tunnel, outskb);
+ __tipc_link_xmit_skb(tunnel, outskb);
if (!tipc_link_is_up(l_ptr))
return;
}
diff --git a/net/tipc/link.h b/net/tipc/link.h
index de7b883..55812e8 100644
--- a/net/tipc/link.h
+++ b/net/tipc/link.h
@@ -213,8 +213,9 @@ struct sk_buff *tipc_link_cmd_reset_stats(const void *req_tlv_area,
void tipc_link_reset_all(struct tipc_node *node);
void tipc_link_reset(struct tipc_link *l_ptr);
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 tipc_link *link, struct sk_buff *buf);
+int tipc_link_xmit_skb(struct sk_buff *skb, u32 dest, u32 selector);
+int tipc_link_xmit(struct sk_buff_head *list, u32 dest, u32 selector);
+int __tipc_link_xmit(struct tipc_link *link, struct sk_buff_head *list);
u32 tipc_link_get_max_pkt(u32 dest, u32 selector);
void tipc_link_bundle_rcv(struct sk_buff *buf);
void tipc_link_proto_xmit(struct tipc_link *l_ptr, u32 msg_typ, int prob,
diff --git a/net/tipc/msg.c b/net/tipc/msg.c
index ce7514a..5b06597 100644
--- a/net/tipc/msg.c
+++ b/net/tipc/msg.c
@@ -166,11 +166,12 @@ err:
* @offset: Posision in iov to start copying from
* @dsz: Total length of user data
* @pktmax: Max packet size that can be used
- * @chain: Buffer or chain of buffers to be returned to caller
+ * @list: Buffer or chain of buffers to be returned to caller
+ *
* Returns message data size or errno: -ENOMEM, -EFAULT
*/
-int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m,
- int offset, int dsz, int pktmax , struct sk_buff **chain)
+int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m, int offset,
+ int dsz, int pktmax, struct sk_buff_head *list)
{
int mhsz = msg_hdr_sz(mhdr);
int msz = mhsz + dsz;
@@ -179,22 +180,22 @@ int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m,
int pktrem = pktmax;
int drem = dsz;
struct tipc_msg pkthdr;
- struct sk_buff *buf, *prev;
+ struct sk_buff *skb;
char *pktpos;
int rc;
- uint chain_sz = 0;
+
msg_set_size(mhdr, msz);
/* No fragmentation needed? */
if (likely(msz <= pktmax)) {
- buf = tipc_buf_acquire(msz);
- *chain = buf;
- if (unlikely(!buf))
+ skb = tipc_buf_acquire(msz);
+ if (unlikely(!skb))
return -ENOMEM;
- skb_copy_to_linear_data(buf, mhdr, mhsz);
- pktpos = buf->data + mhsz;
- TIPC_SKB_CB(buf)->chain_sz = 1;
- if (!dsz || !memcpy_fromiovecend(pktpos, m->msg_iov, offset, dsz))
+ __skb_queue_tail(list, skb);
+ skb_copy_to_linear_data(skb, mhdr, mhsz);
+ pktpos = skb->data + mhsz;
+ if (!dsz || !memcpy_fromiovecend(pktpos, m->msg_iov, offset,
+ dsz))
return dsz;
rc = -EFAULT;
goto error;
@@ -207,15 +208,15 @@ int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m,
msg_set_fragm_no(&pkthdr, pktno);
/* Prepare first fragment */
- *chain = buf = tipc_buf_acquire(pktmax);
- if (!buf)
+ skb = tipc_buf_acquire(pktmax);
+ if (!skb)
return -ENOMEM;
- chain_sz = 1;
- pktpos = buf->data;
- skb_copy_to_linear_data(buf, &pkthdr, INT_H_SIZE);
+ __skb_queue_tail(list, skb);
+ pktpos = skb->data;
+ skb_copy_to_linear_data(skb, &pkthdr, INT_H_SIZE);
pktpos += INT_H_SIZE;
pktrem -= INT_H_SIZE;
- skb_copy_to_linear_data_offset(buf, INT_H_SIZE, mhdr, mhsz);
+ skb_copy_to_linear_data_offset(skb, INT_H_SIZE, mhdr, mhsz);
pktpos += mhsz;
pktrem -= mhsz;
@@ -238,28 +239,25 @@ int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m,
pktsz = drem + INT_H_SIZE;
else
pktsz = pktmax;
- prev = buf;
- buf = tipc_buf_acquire(pktsz);
- if (!buf) {
+ skb = tipc_buf_acquire(pktsz);
+ if (!skb) {
rc = -ENOMEM;
goto error;
}
- chain_sz++;
- prev->next = buf;
+ __skb_queue_tail(list, skb);
msg_set_type(&pkthdr, FRAGMENT);
msg_set_size(&pkthdr, pktsz);
msg_set_fragm_no(&pkthdr, ++pktno);
- skb_copy_to_linear_data(buf, &pkthdr, INT_H_SIZE);
- pktpos = buf->data + INT_H_SIZE;
+ skb_copy_to_linear_data(skb, &pkthdr, INT_H_SIZE);
+ pktpos = skb->data + INT_H_SIZE;
pktrem = pktsz - INT_H_SIZE;
} while (1);
- TIPC_SKB_CB(*chain)->chain_sz = chain_sz;
- msg_set_type(buf_msg(buf), LAST_FRAGMENT);
+ msg_set_type(buf_msg(skb), LAST_FRAGMENT);
return dsz;
error:
- kfree_skb_list(*chain);
- *chain = NULL;
+ __skb_queue_purge(list);
+ __skb_queue_head_init(list);
return rc;
}
@@ -430,22 +428,23 @@ int tipc_msg_eval(struct sk_buff *buf, u32 *dnode)
/* tipc_msg_reassemble() - clone a buffer chain of fragments and
* reassemble the clones into one message
*/
-struct sk_buff *tipc_msg_reassemble(struct sk_buff *chain)
+struct sk_buff *tipc_msg_reassemble(struct sk_buff_head *list)
{
- struct sk_buff *buf = chain;
- struct sk_buff *frag = buf;
+ struct sk_buff *skb;
+ struct sk_buff *frag = NULL;
struct sk_buff *head = NULL;
int hdr_sz;
/* Copy header if single buffer */
- if (!buf->next) {
- hdr_sz = skb_headroom(buf) + msg_hdr_sz(buf_msg(buf));
- return __pskb_copy(buf, hdr_sz, GFP_ATOMIC);
+ if (skb_queue_len(list) == 1) {
+ skb = skb_peek(list);
+ hdr_sz = skb_headroom(skb) + msg_hdr_sz(buf_msg(skb));
+ return __pskb_copy(skb, hdr_sz, GFP_ATOMIC);
}
/* Clone all fragments and reassemble */
- while (buf) {
- frag = skb_clone(buf, GFP_ATOMIC);
+ skb_queue_walk(list, skb) {
+ frag = skb_clone(skb, GFP_ATOMIC);
if (!frag)
goto error;
frag->next = NULL;
@@ -453,7 +452,6 @@ struct sk_buff *tipc_msg_reassemble(struct sk_buff *chain)
break;
if (!head)
goto error;
- buf = buf->next;
}
return frag;
error:
diff --git a/net/tipc/msg.h b/net/tipc/msg.h
index 53e425f..d5c83d7 100644
--- a/net/tipc/msg.h
+++ b/net/tipc/msg.h
@@ -739,9 +739,9 @@ bool tipc_msg_bundle(struct sk_buff_head *list, struct sk_buff *skb, u32 mtu);
bool tipc_msg_make_bundle(struct sk_buff_head *list, struct sk_buff *skb,
u32 mtu, u32 dnode);
-int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m,
- int offset, int dsz, int mtu , struct sk_buff **chain);
+int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m, int offset,
+ int dsz, int mtu, struct sk_buff_head *list);
-struct sk_buff *tipc_msg_reassemble(struct sk_buff *chain);
+struct sk_buff *tipc_msg_reassemble(struct sk_buff_head *list);
#endif
diff --git a/net/tipc/name_distr.c b/net/tipc/name_distr.c
index 6c2638d..56248db 100644
--- a/net/tipc/name_distr.c
+++ b/net/tipc/name_distr.c
@@ -114,9 +114,9 @@ static struct sk_buff *named_prepare_buf(u32 type, u32 size, u32 dest)
return buf;
}
-void named_cluster_distribute(struct sk_buff *buf)
+void named_cluster_distribute(struct sk_buff *skb)
{
- struct sk_buff *obuf;
+ struct sk_buff *oskb;
struct tipc_node *node;
u32 dnode;
@@ -127,15 +127,15 @@ void named_cluster_distribute(struct sk_buff *buf)
continue;
if (!tipc_node_active_links(node))
continue;
- obuf = skb_copy(buf, GFP_ATOMIC);
- if (!obuf)
+ oskb = skb_copy(skb, GFP_ATOMIC);
+ if (!oskb)
break;
- msg_set_destnode(buf_msg(obuf), dnode);
- tipc_link_xmit(obuf, dnode, dnode);
+ msg_set_destnode(buf_msg(oskb), dnode);
+ tipc_link_xmit_skb(oskb, dnode, dnode);
}
rcu_read_unlock();
- kfree_skb(buf);
+ kfree_skb(skb);
}
/**
@@ -190,15 +190,15 @@ struct sk_buff *tipc_named_withdraw(struct publication *publ)
/**
* named_distribute - prepare name info for bulk distribution to another node
- * @msg_list: list of messages (buffers) to be returned from this function
+ * @list: list of messages (buffers) to be returned from this function
* @dnode: node to be updated
* @pls: linked list of publication items to be packed into buffer chain
*/
-static void named_distribute(struct list_head *msg_list, u32 dnode,
+static void named_distribute(struct sk_buff_head *list, u32 dnode,
struct publ_list *pls)
{
struct publication *publ;
- struct sk_buff *buf = NULL;
+ struct sk_buff *skb = NULL;
struct distr_item *item = NULL;
uint dsz = pls->size * ITEM_SIZE;
uint msg_dsz = (tipc_node_get_mtu(dnode, 0) / ITEM_SIZE) * ITEM_SIZE;
@@ -207,15 +207,15 @@ static void named_distribute(struct list_head *msg_list, u32 dnode,
list_for_each_entry(publ, &pls->list, local_list) {
/* Prepare next buffer: */
- if (!buf) {
+ if (!skb) {
msg_rem = min_t(uint, rem, msg_dsz);
rem -= msg_rem;
- buf = named_prepare_buf(PUBLICATION, msg_rem, dnode);
- if (!buf) {
+ skb = named_prepare_buf(PUBLICATION, msg_rem, dnode);
+ if (!skb) {
pr_warn("Bulk publication failure\n");
return;
}
- item = (struct distr_item *)msg_data(buf_msg(buf));
+ item = (struct distr_item *)msg_data(buf_msg(skb));
}
/* Pack publication into message: */
@@ -225,8 +225,8 @@ static void named_distribute(struct list_head *msg_list, u32 dnode,
/* Append full buffer to list: */
if (!msg_rem) {
- list_add_tail((struct list_head *)buf, msg_list);
- buf = NULL;
+ __skb_queue_tail(list, skb);
+ skb = NULL;
}
}
}
@@ -236,18 +236,16 @@ static void named_distribute(struct list_head *msg_list, u32 dnode,
*/
void tipc_named_node_up(u32 dnode)
{
- LIST_HEAD(msg_list);
- struct sk_buff *buf_chain;
+ struct sk_buff_head head;
+
+ __skb_queue_head_init(&head);
read_lock_bh(&tipc_nametbl_lock);
- named_distribute(&msg_list, dnode, &publ_cluster);
- named_distribute(&msg_list, dnode, &publ_zone);
+ named_distribute(&head, dnode, &publ_cluster);
+ named_distribute(&head, dnode, &publ_zone);
read_unlock_bh(&tipc_nametbl_lock);
- /* Convert circular list to linear list and send: */
- buf_chain = (struct sk_buff *)msg_list.next;
- ((struct sk_buff *)msg_list.prev)->next = NULL;
- tipc_link_xmit(buf_chain, dnode, dnode);
+ tipc_link_xmit(&head, dnode, dnode);
}
static void tipc_publ_subscribe(struct publication *publ, u32 addr)
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 341fbd1..9658d9b 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -244,12 +244,12 @@ static void tsk_advance_rx_queue(struct sock *sk)
*/
static void tsk_rej_rx_queue(struct sock *sk)
{
- struct sk_buff *buf;
+ struct sk_buff *skb;
u32 dnode;
- while ((buf = __skb_dequeue(&sk->sk_receive_queue))) {
- if (tipc_msg_reverse(buf, &dnode, TIPC_ERR_NO_PORT))
- tipc_link_xmit(buf, dnode, 0);
+ while ((skb = __skb_dequeue(&sk->sk_receive_queue))) {
+ if (tipc_msg_reverse(skb, &dnode, TIPC_ERR_NO_PORT))
+ tipc_link_xmit_skb(skb, dnode, 0);
}
}
@@ -462,7 +462,7 @@ static int tipc_release(struct socket *sock)
{
struct sock *sk = sock->sk;
struct tipc_sock *tsk;
- struct sk_buff *buf;
+ struct sk_buff *skb;
u32 dnode;
/*
@@ -481,11 +481,11 @@ static int tipc_release(struct socket *sock)
*/
dnode = tsk_peer_node(tsk);
while (sock->state != SS_DISCONNECTING) {
- buf = __skb_dequeue(&sk->sk_receive_queue);
- if (buf == NULL)
+ skb = __skb_dequeue(&sk->sk_receive_queue);
+ if (skb == NULL)
break;
- if (TIPC_SKB_CB(buf)->handle != NULL)
- kfree_skb(buf);
+ if (TIPC_SKB_CB(skb)->handle != NULL)
+ kfree_skb(skb);
else {
if ((sock->state == SS_CONNECTING) ||
(sock->state == SS_CONNECTED)) {
@@ -493,8 +493,8 @@ static int tipc_release(struct socket *sock)
tsk->connected = 0;
tipc_node_remove_conn(dnode, tsk->ref);
}
- if (tipc_msg_reverse(buf, &dnode, TIPC_ERR_NO_PORT))
- tipc_link_xmit(buf, dnode, 0);
+ if (tipc_msg_reverse(skb, &dnode, TIPC_ERR_NO_PORT))
+ tipc_link_xmit_skb(skb, dnode, 0);
}
}
@@ -502,12 +502,12 @@ static int tipc_release(struct socket *sock)
tipc_sk_ref_discard(tsk->ref);
k_cancel_timer(&tsk->timer);
if (tsk->connected) {
- buf = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE, TIPC_CONN_MSG,
+ skb = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE, TIPC_CONN_MSG,
SHORT_H_SIZE, 0, dnode, tipc_own_addr,
tsk_peer_port(tsk),
tsk->ref, TIPC_ERR_NO_PORT);
- if (buf)
- tipc_link_xmit(buf, dnode, tsk->ref);
+ if (skb)
+ tipc_link_xmit_skb(skb, dnode, tsk->ref);
tipc_node_remove_conn(dnode, tsk->ref);
}
k_term_timer(&tsk->timer);
@@ -712,7 +712,7 @@ static int tipc_sendmcast(struct socket *sock, struct tipc_name_seq *seq,
{
struct sock *sk = sock->sk;
struct tipc_msg *mhdr = &tipc_sk(sk)->phdr;
- struct sk_buff *buf;
+ struct sk_buff_head head;
uint mtu;
int rc;
@@ -727,12 +727,13 @@ static int tipc_sendmcast(struct socket *sock, struct tipc_name_seq *seq,
new_mtu:
mtu = tipc_bclink_get_mtu();
- rc = tipc_msg_build(mhdr, msg, 0, dsz, mtu, &buf);
+ __skb_queue_head_init(&head);
+ rc = tipc_msg_build(mhdr, msg, 0, dsz, mtu, &head);
if (unlikely(rc < 0))
return rc;
do {
- rc = tipc_bclink_xmit(buf);
+ rc = tipc_bclink_xmit(&head);
if (likely(rc >= 0)) {
rc = dsz;
break;
@@ -744,7 +745,7 @@ new_mtu:
tipc_sk(sk)->link_cong = 1;
rc = tipc_wait_for_sndmsg(sock, &timeo);
if (rc)
- kfree_skb_list(buf);
+ __skb_queue_purge(&head);
} while (!rc);
return rc;
}
@@ -906,7 +907,8 @@ static int tipc_sendmsg(struct kiocb *iocb, struct socket *sock,
struct tipc_sock *tsk = tipc_sk(sk);
struct tipc_msg *mhdr = &tsk->phdr;
u32 dnode, dport;
- struct sk_buff *buf;
+ struct sk_buff_head head;
+ struct sk_buff *skb;
struct tipc_name_seq *seq = &dest->addr.nameseq;
u32 mtu;
long timeo;
@@ -981,13 +983,15 @@ static int tipc_sendmsg(struct kiocb *iocb, struct socket *sock,
new_mtu:
mtu = tipc_node_get_mtu(dnode, tsk->ref);
- rc = tipc_msg_build(mhdr, m, 0, dsz, mtu, &buf);
+ __skb_queue_head_init(&head);
+ rc = tipc_msg_build(mhdr, m, 0, dsz, mtu, &head);
if (rc < 0)
goto exit;
do {
- TIPC_SKB_CB(buf)->wakeup_pending = tsk->link_cong;
- rc = tipc_link_xmit(buf, dnode, tsk->ref);
+ skb = skb_peek(&head);
+ TIPC_SKB_CB(skb)->wakeup_pending = tsk->link_cong;
+ rc = tipc_link_xmit(&head, dnode, tsk->ref);
if (likely(rc >= 0)) {
if (sock->state != SS_READY)
sock->state = SS_CONNECTING;
@@ -1001,7 +1005,7 @@ new_mtu:
tsk->link_cong = 1;
rc = tipc_wait_for_sndmsg(sock, &timeo);
if (rc)
- kfree_skb_list(buf);
+ __skb_queue_purge(&head);
} while (!rc);
exit:
if (iocb)
@@ -1058,7 +1062,7 @@ static int tipc_send_stream(struct kiocb *iocb, struct socket *sock,
struct sock *sk = sock->sk;
struct tipc_sock *tsk = tipc_sk(sk);
struct tipc_msg *mhdr = &tsk->phdr;
- struct sk_buff *buf;
+ struct sk_buff_head head;
DECLARE_SOCKADDR(struct sockaddr_tipc *, dest, m->msg_name);
u32 ref = tsk->ref;
int rc = -EINVAL;
@@ -1093,12 +1097,13 @@ static int tipc_send_stream(struct kiocb *iocb, struct socket *sock,
next:
mtu = tsk->max_pkt;
send = min_t(uint, dsz - sent, TIPC_MAX_USER_MSG_SIZE);
- rc = tipc_msg_build(mhdr, m, sent, send, mtu, &buf);
+ __skb_queue_head_init(&head);
+ rc = tipc_msg_build(mhdr, m, sent, send, mtu, &head);
if (unlikely(rc < 0))
goto exit;
do {
if (likely(!tsk_conn_cong(tsk))) {
- rc = tipc_link_xmit(buf, dnode, ref);
+ rc = tipc_link_xmit(&head, dnode, ref);
if (likely(!rc)) {
tsk->sent_unacked++;
sent += send;
@@ -1116,7 +1121,7 @@ next:
}
rc = tipc_wait_for_sndpkt(sock, &timeo);
if (rc)
- kfree_skb_list(buf);
+ __skb_queue_purge(&head);
} while (!rc);
exit:
if (iocb)
@@ -1261,20 +1266,20 @@ static int tipc_sk_anc_data_recv(struct msghdr *m, struct tipc_msg *msg,
static void tipc_sk_send_ack(struct tipc_sock *tsk, uint ack)
{
- struct sk_buff *buf = NULL;
+ struct sk_buff *skb = NULL;
struct tipc_msg *msg;
u32 peer_port = tsk_peer_port(tsk);
u32 dnode = tsk_peer_node(tsk);
if (!tsk->connected)
return;
- buf = tipc_msg_create(CONN_MANAGER, CONN_ACK, INT_H_SIZE, 0, dnode,
+ skb = tipc_msg_create(CONN_MANAGER, CONN_ACK, INT_H_SIZE, 0, dnode,
tipc_own_addr, peer_port, tsk->ref, TIPC_OK);
- if (!buf)
+ if (!skb)
return;
- msg = buf_msg(buf);
+ msg = buf_msg(skb);
msg_set_msgcnt(msg, ack);
- tipc_link_xmit(buf, dnode, msg_link_selector(msg));
+ tipc_link_xmit_skb(skb, dnode, msg_link_selector(msg));
}
static int tipc_wait_for_rcvmsg(struct socket *sock, long *timeop)
@@ -1729,20 +1734,20 @@ static int filter_rcv(struct sock *sk, struct sk_buff *buf)
/**
* tipc_backlog_rcv - handle incoming message from backlog queue
* @sk: socket
- * @buf: message
+ * @skb: message
*
* Caller must hold socket lock, but not port lock.
*
* Returns 0
*/
-static int tipc_backlog_rcv(struct sock *sk, struct sk_buff *buf)
+static int tipc_backlog_rcv(struct sock *sk, struct sk_buff *skb)
{
int rc;
u32 onode;
struct tipc_sock *tsk = tipc_sk(sk);
- uint truesize = buf->truesize;
+ uint truesize = skb->truesize;
- rc = filter_rcv(sk, buf);
+ rc = filter_rcv(sk, skb);
if (likely(!rc)) {
if (atomic_read(&tsk->dupl_rcvcnt) < TIPC_CONN_OVERLOAD_LIMIT)
@@ -1750,25 +1755,25 @@ static int tipc_backlog_rcv(struct sock *sk, struct sk_buff *buf)
return 0;
}
- if ((rc < 0) && !tipc_msg_reverse(buf, &onode, -rc))
+ if ((rc < 0) && !tipc_msg_reverse(skb, &onode, -rc))
return 0;
- tipc_link_xmit(buf, onode, 0);
+ tipc_link_xmit_skb(skb, onode, 0);
return 0;
}
/**
* tipc_sk_rcv - handle incoming message
- * @buf: buffer containing arriving message
+ * @skb: buffer containing arriving message
* Consumes buffer
* Returns 0 if success, or errno: -EHOSTUNREACH
*/
-int tipc_sk_rcv(struct sk_buff *buf)
+int tipc_sk_rcv(struct sk_buff *skb)
{
struct tipc_sock *tsk;
struct sock *sk;
- u32 dport = msg_destport(buf_msg(buf));
+ u32 dport = msg_destport(buf_msg(skb));
int rc = TIPC_OK;
uint limit;
u32 dnode;
@@ -1776,7 +1781,7 @@ int tipc_sk_rcv(struct sk_buff *buf)
/* Validate destination and message */
tsk = tipc_sk_get(dport);
if (unlikely(!tsk)) {
- rc = tipc_msg_eval(buf, &dnode);
+ rc = tipc_msg_eval(skb, &dnode);
goto exit;
}
sk = &tsk->sk;
@@ -1785,12 +1790,12 @@ int tipc_sk_rcv(struct sk_buff *buf)
spin_lock_bh(&sk->sk_lock.slock);
if (!sock_owned_by_user(sk)) {
- rc = filter_rcv(sk, buf);
+ rc = filter_rcv(sk, skb);
} else {
if (sk->sk_backlog.len == 0)
atomic_set(&tsk->dupl_rcvcnt, 0);
- limit = rcvbuf_limit(sk, buf) + atomic_read(&tsk->dupl_rcvcnt);
- if (sk_add_backlog(sk, buf, limit))
+ limit = rcvbuf_limit(sk, skb) + atomic_read(&tsk->dupl_rcvcnt);
+ if (sk_add_backlog(sk, skb, limit))
rc = -TIPC_ERR_OVERLOAD;
}
spin_unlock_bh(&sk->sk_lock.slock);
@@ -1798,10 +1803,10 @@ int tipc_sk_rcv(struct sk_buff *buf)
if (likely(!rc))
return 0;
exit:
- if ((rc < 0) && !tipc_msg_reverse(buf, &dnode, -rc))
+ if ((rc < 0) && !tipc_msg_reverse(skb, &dnode, -rc))
return -EHOSTUNREACH;
- tipc_link_xmit(buf, dnode, 0);
+ tipc_link_xmit_skb(skb, dnode, 0);
return (rc < 0) ? -EHOSTUNREACH : 0;
}
@@ -2059,7 +2064,7 @@ static int tipc_shutdown(struct socket *sock, int how)
{
struct sock *sk = sock->sk;
struct tipc_sock *tsk = tipc_sk(sk);
- struct sk_buff *buf;
+ struct sk_buff *skb;
u32 dnode;
int res;
@@ -2074,23 +2079,23 @@ static int tipc_shutdown(struct socket *sock, int how)
restart:
/* Disconnect and send a 'FIN+' or 'FIN-' message to peer */
- buf = __skb_dequeue(&sk->sk_receive_queue);
- if (buf) {
- if (TIPC_SKB_CB(buf)->handle != NULL) {
- kfree_skb(buf);
+ skb = __skb_dequeue(&sk->sk_receive_queue);
+ if (skb) {
+ if (TIPC_SKB_CB(skb)->handle != NULL) {
+ kfree_skb(skb);
goto restart;
}
- if (tipc_msg_reverse(buf, &dnode, TIPC_CONN_SHUTDOWN))
- tipc_link_xmit(buf, dnode, tsk->ref);
+ if (tipc_msg_reverse(skb, &dnode, TIPC_CONN_SHUTDOWN))
+ tipc_link_xmit_skb(skb, dnode, tsk->ref);
tipc_node_remove_conn(dnode, tsk->ref);
} else {
dnode = tsk_peer_node(tsk);
- buf = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE,
+ skb = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE,
TIPC_CONN_MSG, SHORT_H_SIZE,
0, dnode, tipc_own_addr,
tsk_peer_port(tsk),
tsk->ref, TIPC_CONN_SHUTDOWN);
- tipc_link_xmit(buf, dnode, tsk->ref);
+ tipc_link_xmit_skb(skb, dnode, tsk->ref);
}
tsk->connected = 0;
sock->state = SS_DISCONNECTING;
@@ -2119,7 +2124,7 @@ static void tipc_sk_timeout(unsigned long ref)
{
struct tipc_sock *tsk;
struct sock *sk;
- struct sk_buff *buf = NULL;
+ struct sk_buff *skb = NULL;
u32 peer_port, peer_node;
tsk = tipc_sk_get(ref);
@@ -2137,20 +2142,20 @@ static void tipc_sk_timeout(unsigned long ref)
if (tsk->probing_state == TIPC_CONN_PROBING) {
/* Previous probe not answered -> self abort */
- buf = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE, TIPC_CONN_MSG,
+ skb = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE, TIPC_CONN_MSG,
SHORT_H_SIZE, 0, tipc_own_addr,
peer_node, ref, peer_port,
TIPC_ERR_NO_PORT);
} else {
- buf = tipc_msg_create(CONN_MANAGER, CONN_PROBE, INT_H_SIZE,
+ skb = tipc_msg_create(CONN_MANAGER, CONN_PROBE, INT_H_SIZE,
0, peer_node, tipc_own_addr,
peer_port, ref, TIPC_OK);
tsk->probing_state = TIPC_CONN_PROBING;
k_start_timer(&tsk->timer, tsk->probing_interval);
}
bh_unlock_sock(sk);
- if (buf)
- tipc_link_xmit(buf, peer_node, ref);
+ if (skb)
+ tipc_link_xmit_skb(skb, peer_node, ref);
exit:
tipc_sk_put(tsk);
}
--
1.7.9.5
------------------------------------------------------------------------------
Download BIRT iHub F-Type - The Free Enterprise-Grade BIRT Server
from Actuate! Instantly Supercharge Your Business Reports and Dashboards
with Interactivity, Sharing, Native Excel Exports, App Integration & more
Get technology previously reserved for billion-dollar corporations, FREE
http://pubads.g.doubleclick.net/gampad/clk?id=157005751&iu=/4140/ostg.clktrk
^ permalink raw reply related
* [PATCH net-next 10/11] tipc: use generic SKB list APIs to manage link receive queue
From: Ying Xue @ 2014-11-26 3:41 UTC (permalink / raw)
To: davem; +Cc: jon.maloy, netdev, Paul.Gortmaker, tipc-discussion
In-Reply-To: <1416973315-6047-1-git-send-email-ying.xue@windriver.com>
Use standard SKB list APIs associated with struct sk_buff_head to
manage link's receive queue to simplify its relevant code cemplexity.
Signed-off-by: Ying Xue <ying.xue@windriver.com>
Reviewed-by: Jon Maloy <jon.maloy@ericsson.com>
---
net/tipc/bearer.h | 2 +-
net/tipc/link.c | 85 +++++++++++++++++++++++------------------------------
2 files changed, 37 insertions(+), 50 deletions(-)
diff --git a/net/tipc/bearer.h b/net/tipc/bearer.h
index b1d9052..2c1230a 100644
--- a/net/tipc/bearer.h
+++ b/net/tipc/bearer.h
@@ -165,7 +165,7 @@ extern struct tipc_bearer __rcu *bearer_list[];
* TIPC routines available to supported media types
*/
-void tipc_rcv(struct sk_buff *buf, struct tipc_bearer *tb_ptr);
+void tipc_rcv(struct sk_buff *skb, struct tipc_bearer *tb_ptr);
int tipc_enable_bearer(const char *bearer_name, u32 disc_domain, u32 priority);
int tipc_disable_bearer(const char *name);
diff --git a/net/tipc/link.c b/net/tipc/link.c
index d9c2310..0e04508 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -966,29 +966,17 @@ void tipc_link_retransmit(struct tipc_link *l_ptr, struct sk_buff *skb,
}
}
-/**
- * link_insert_deferred_queue - insert deferred messages back into receive chain
- */
-static struct sk_buff *link_insert_deferred_queue(struct tipc_link *l_ptr,
- struct sk_buff *buf)
+static void link_retrieve_defq(struct tipc_link *link,
+ struct sk_buff_head *list)
{
- struct sk_buff_head head;
- struct sk_buff *skb = NULL;
u32 seq_no;
- if (skb_queue_empty(&l_ptr->deferred_queue))
- return buf;
-
- seq_no = buf_seqno(skb_peek(&l_ptr->deferred_queue));
- if (seq_no == mod(l_ptr->next_in_no)) {
- __skb_queue_head_init(&head);
- skb_queue_splice_tail_init(&l_ptr->deferred_queue, &head);
- skb = head.next;
- skb->prev = NULL;
- head.prev->next = buf;
- head.prev->prev = NULL;
- }
- return skb;
+ if (skb_queue_empty(&link->deferred_queue))
+ return;
+
+ seq_no = buf_seqno(skb_peek(&link->deferred_queue));
+ if (seq_no == mod(link->next_in_no))
+ skb_queue_splice_tail_init(&link->deferred_queue, list);
}
/**
@@ -1048,43 +1036,43 @@ static int link_recv_buf_validate(struct sk_buff *buf)
/**
* tipc_rcv - process TIPC packets/messages arriving from off-node
- * @head: pointer to message buffer chain
+ * @skb: TIPC packet
* @b_ptr: pointer to bearer message arrived on
*
* Invoked with no locks held. Bearer pointer must point to a valid bearer
* structure (i.e. cannot be NULL), but bearer can be inactive.
*/
-void tipc_rcv(struct sk_buff *head, struct tipc_bearer *b_ptr)
+void tipc_rcv(struct sk_buff *skb, struct tipc_bearer *b_ptr)
{
- while (head) {
- struct tipc_node *n_ptr;
- struct tipc_link *l_ptr;
- struct sk_buff *buf = head;
- struct sk_buff *skb1, *tmp;
- struct tipc_msg *msg;
- u32 seq_no;
- u32 ackd;
- u32 released;
+ struct sk_buff_head head;
+ struct tipc_node *n_ptr;
+ struct tipc_link *l_ptr;
+ struct sk_buff *skb1, *tmp;
+ struct tipc_msg *msg;
+ u32 seq_no;
+ u32 ackd;
+ u32 released;
- head = head->next;
- buf->next = NULL;
+ __skb_queue_head_init(&head);
+ __skb_queue_tail(&head, skb);
+ while ((skb = __skb_dequeue(&head))) {
/* Ensure message is well-formed */
- if (unlikely(!link_recv_buf_validate(buf)))
+ if (unlikely(!link_recv_buf_validate(skb)))
goto discard;
/* Ensure message data is a single contiguous unit */
- if (unlikely(skb_linearize(buf)))
+ if (unlikely(skb_linearize(skb)))
goto discard;
/* Handle arrival of a non-unicast link message */
- msg = buf_msg(buf);
+ msg = buf_msg(skb);
if (unlikely(msg_non_seq(msg))) {
if (msg_user(msg) == LINK_CONFIG)
- tipc_disc_rcv(buf, b_ptr);
+ tipc_disc_rcv(skb, b_ptr);
else
- tipc_bclink_rcv(buf);
+ tipc_bclink_rcv(skb);
continue;
}
@@ -1145,8 +1133,8 @@ void tipc_rcv(struct sk_buff *head, struct tipc_bearer *b_ptr)
/* Process the incoming packet */
if (unlikely(!link_working_working(l_ptr))) {
if (msg_user(msg) == LINK_PROTOCOL) {
- tipc_link_proto_rcv(l_ptr, buf);
- head = link_insert_deferred_queue(l_ptr, head);
+ tipc_link_proto_rcv(l_ptr, skb);
+ link_retrieve_defq(l_ptr, &head);
tipc_node_unlock(n_ptr);
continue;
}
@@ -1156,8 +1144,7 @@ void tipc_rcv(struct sk_buff *head, struct tipc_bearer *b_ptr)
if (link_working_working(l_ptr)) {
/* Re-insert buffer in front of queue */
- buf->next = head;
- head = buf;
+ __skb_queue_head(&head, skb);
tipc_node_unlock(n_ptr);
continue;
}
@@ -1166,33 +1153,33 @@ void tipc_rcv(struct sk_buff *head, struct tipc_bearer *b_ptr)
/* Link is now in state WORKING_WORKING */
if (unlikely(seq_no != mod(l_ptr->next_in_no))) {
- link_handle_out_of_seq_msg(l_ptr, buf);
- head = link_insert_deferred_queue(l_ptr, head);
+ link_handle_out_of_seq_msg(l_ptr, skb);
+ link_retrieve_defq(l_ptr, &head);
tipc_node_unlock(n_ptr);
continue;
}
l_ptr->next_in_no++;
if (unlikely(!skb_queue_empty(&l_ptr->deferred_queue)))
- head = link_insert_deferred_queue(l_ptr, head);
+ link_retrieve_defq(l_ptr, &head);
if (unlikely(++l_ptr->unacked_window >= TIPC_MIN_LINK_WIN)) {
l_ptr->stats.sent_acks++;
tipc_link_proto_xmit(l_ptr, STATE_MSG, 0, 0, 0, 0, 0);
}
- if (tipc_link_prepare_input(l_ptr, &buf)) {
+ if (tipc_link_prepare_input(l_ptr, &skb)) {
tipc_node_unlock(n_ptr);
continue;
}
tipc_node_unlock(n_ptr);
- msg = buf_msg(buf);
- if (tipc_link_input(l_ptr, buf) != 0)
+
+ if (tipc_link_input(l_ptr, skb) != 0)
goto discard;
continue;
unlock_discard:
tipc_node_unlock(n_ptr);
discard:
- kfree_skb(buf);
+ kfree_skb(skb);
}
}
--
1.7.9.5
------------------------------------------------------------------------------
Download BIRT iHub F-Type - The Free Enterprise-Grade BIRT Server
from Actuate! Instantly Supercharge Your Business Reports and Dashboards
with Interactivity, Sharing, Native Excel Exports, App Integration & more
Get technology previously reserved for billion-dollar corporations, FREE
http://pubads.g.doubleclick.net/gampad/clk?id=157005751&iu=/4140/ostg.clktrk
^ permalink raw reply related
* [PATCH net-next 09/11] tipc: use generic SKB list APIs to manage deferred queue of link
From: Ying Xue @ 2014-11-26 3:41 UTC (permalink / raw)
To: davem; +Cc: jon.maloy, netdev, Paul.Gortmaker, tipc-discussion
In-Reply-To: <1416973315-6047-1-git-send-email-ying.xue@windriver.com>
Use standard SKB list APIs associated with struct sk_buff_head to
manage link's deferred queue, simplifying relevant code.
Signed-off-by: Ying Xue <ying.xue@windriver.com>
Reviewed-by: Jon Maloy <jon.maloy@ericsson.com>
---
net/tipc/bcast.c | 20 ++++++---------
net/tipc/link.c | 74 +++++++++++++++++++++++-------------------------------
net/tipc/link.h | 11 +++-----
net/tipc/node.c | 4 +--
net/tipc/node.h | 7 ++----
5 files changed, 47 insertions(+), 69 deletions(-)
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c
index 4a1a3c8..7b238b1 100644
--- a/net/tipc/bcast.c
+++ b/net/tipc/bcast.c
@@ -352,6 +352,8 @@ void tipc_bclink_update_link_state(struct tipc_node *n_ptr, u32 last_sent)
buf = tipc_buf_acquire(INT_H_SIZE);
if (buf) {
struct tipc_msg *msg = buf_msg(buf);
+ struct sk_buff *skb = skb_peek(&n_ptr->bclink.deferred_queue);
+ u32 to = skb ? buf_seqno(skb) - 1 : n_ptr->bclink.last_sent;
tipc_msg_init(msg, BCAST_PROTOCOL, STATE_MSG,
INT_H_SIZE, n_ptr->addr);
@@ -359,9 +361,7 @@ void tipc_bclink_update_link_state(struct tipc_node *n_ptr, u32 last_sent)
msg_set_mc_netid(msg, tipc_net_id);
msg_set_bcast_ack(msg, n_ptr->bclink.last_in);
msg_set_bcgap_after(msg, n_ptr->bclink.last_in);
- msg_set_bcgap_to(msg, n_ptr->bclink.deferred_head
- ? buf_seqno(n_ptr->bclink.deferred_head) - 1
- : n_ptr->bclink.last_sent);
+ msg_set_bcgap_to(msg, to);
tipc_bclink_lock();
tipc_bearer_send(MAX_BEARERS, buf, NULL);
@@ -574,31 +574,26 @@ receive:
if (node->bclink.last_in == node->bclink.last_sent)
goto unlock;
- if (!node->bclink.deferred_head) {
+ if (skb_queue_empty(&node->bclink.deferred_queue)) {
node->bclink.oos_state = 1;
goto unlock;
}
- msg = buf_msg(node->bclink.deferred_head);
+ msg = buf_msg(skb_peek(&node->bclink.deferred_queue));
seqno = msg_seqno(msg);
next_in = mod(next_in + 1);
if (seqno != next_in)
goto unlock;
/* Take in-sequence message from deferred queue & deliver it */
- buf = node->bclink.deferred_head;
- node->bclink.deferred_head = buf->next;
- buf->next = NULL;
- node->bclink.deferred_size--;
+ buf = __skb_dequeue(&node->bclink.deferred_queue);
goto receive;
}
/* Handle out-of-sequence broadcast message */
if (less(next_in, seqno)) {
- deferred = tipc_link_defer_pkt(&node->bclink.deferred_head,
- &node->bclink.deferred_tail,
+ deferred = tipc_link_defer_pkt(&node->bclink.deferred_queue,
buf);
- node->bclink.deferred_size += deferred;
bclink_update_last_sent(node, seqno);
buf = NULL;
}
@@ -954,6 +949,7 @@ int tipc_bclink_init(void)
spin_lock_init(&bclink->lock);
__skb_queue_head_init(&bcl->outqueue);
+ __skb_queue_head_init(&bcl->deferred_queue);
__skb_queue_head_init(&bcl->waiting_sks);
bcl->next_out_no = 1;
spin_lock_init(&bclink->node.lock);
diff --git a/net/tipc/link.c b/net/tipc/link.c
index 9e94bf9..d9c2310 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -292,6 +292,7 @@ struct tipc_link *tipc_link_create(struct tipc_node *n_ptr,
l_ptr->next_out_no = 1;
__skb_queue_head_init(&l_ptr->outqueue);
+ __skb_queue_head_init(&l_ptr->deferred_queue);
__skb_queue_head_init(&l_ptr->waiting_sks);
link_reset_statistics(l_ptr);
@@ -398,7 +399,7 @@ void tipc_link_reset_fragments(struct tipc_link *l_ptr)
*/
void tipc_link_purge_queues(struct tipc_link *l_ptr)
{
- kfree_skb_list(l_ptr->oldest_deferred_in);
+ __skb_queue_purge(&l_ptr->deferred_queue);
__skb_queue_purge(&l_ptr->outqueue);
tipc_link_reset_fragments(l_ptr);
}
@@ -433,7 +434,7 @@ void tipc_link_reset(struct tipc_link *l_ptr)
/* Clean up all queues: */
__skb_queue_purge(&l_ptr->outqueue);
- kfree_skb_list(l_ptr->oldest_deferred_in);
+ __skb_queue_purge(&l_ptr->deferred_queue);
if (!skb_queue_empty(&l_ptr->waiting_sks)) {
skb_queue_splice_init(&l_ptr->waiting_sks, &owner->waiting_sks);
owner->action_flags |= TIPC_WAKEUP_USERS;
@@ -442,9 +443,6 @@ void tipc_link_reset(struct tipc_link *l_ptr)
l_ptr->unacked_window = 0;
l_ptr->checkpoint = 1;
l_ptr->next_out_no = 1;
- l_ptr->deferred_inqueue_sz = 0;
- l_ptr->oldest_deferred_in = NULL;
- l_ptr->newest_deferred_in = NULL;
l_ptr->fsm_msg_cnt = 0;
l_ptr->stale_count = 0;
link_reset_statistics(l_ptr);
@@ -974,19 +972,23 @@ void tipc_link_retransmit(struct tipc_link *l_ptr, struct sk_buff *skb,
static struct sk_buff *link_insert_deferred_queue(struct tipc_link *l_ptr,
struct sk_buff *buf)
{
+ struct sk_buff_head head;
+ struct sk_buff *skb = NULL;
u32 seq_no;
- if (l_ptr->oldest_deferred_in == NULL)
+ if (skb_queue_empty(&l_ptr->deferred_queue))
return buf;
- seq_no = buf_seqno(l_ptr->oldest_deferred_in);
+ seq_no = buf_seqno(skb_peek(&l_ptr->deferred_queue));
if (seq_no == mod(l_ptr->next_in_no)) {
- l_ptr->newest_deferred_in->next = buf;
- buf = l_ptr->oldest_deferred_in;
- l_ptr->oldest_deferred_in = NULL;
- l_ptr->deferred_inqueue_sz = 0;
+ __skb_queue_head_init(&head);
+ skb_queue_splice_tail_init(&l_ptr->deferred_queue, &head);
+ skb = head.next;
+ skb->prev = NULL;
+ head.prev->next = buf;
+ head.prev->prev = NULL;
}
- return buf;
+ return skb;
}
/**
@@ -1170,7 +1172,7 @@ void tipc_rcv(struct sk_buff *head, struct tipc_bearer *b_ptr)
continue;
}
l_ptr->next_in_no++;
- if (unlikely(l_ptr->oldest_deferred_in))
+ if (unlikely(!skb_queue_empty(&l_ptr->deferred_queue)))
head = link_insert_deferred_queue(l_ptr, head);
if (unlikely(++l_ptr->unacked_window >= TIPC_MIN_LINK_WIN)) {
@@ -1273,48 +1275,37 @@ static int tipc_link_input(struct tipc_link *l, struct sk_buff *buf)
*
* Returns increase in queue length (i.e. 0 or 1)
*/
-u32 tipc_link_defer_pkt(struct sk_buff **head, struct sk_buff **tail,
- struct sk_buff *buf)
+u32 tipc_link_defer_pkt(struct sk_buff_head *list, struct sk_buff *skb)
{
- struct sk_buff *queue_buf;
- struct sk_buff **prev;
- u32 seq_no = buf_seqno(buf);
-
- buf->next = NULL;
+ struct sk_buff *skb1;
+ u32 seq_no = buf_seqno(skb);
/* Empty queue ? */
- if (*head == NULL) {
- *head = *tail = buf;
+ if (skb_queue_empty(list)) {
+ __skb_queue_tail(list, skb);
return 1;
}
/* Last ? */
- if (less(buf_seqno(*tail), seq_no)) {
- (*tail)->next = buf;
- *tail = buf;
+ if (less(buf_seqno(skb_peek_tail(list)), seq_no)) {
+ __skb_queue_tail(list, skb);
return 1;
}
/* Locate insertion point in queue, then insert; discard if duplicate */
- prev = head;
- queue_buf = *head;
- for (;;) {
- u32 curr_seqno = buf_seqno(queue_buf);
+ skb_queue_walk(list, skb1) {
+ u32 curr_seqno = buf_seqno(skb1);
if (seq_no == curr_seqno) {
- kfree_skb(buf);
+ kfree_skb(skb);
return 0;
}
if (less(seq_no, curr_seqno))
break;
-
- prev = &queue_buf->next;
- queue_buf = queue_buf->next;
}
- buf->next = queue_buf;
- *prev = buf;
+ __skb_queue_before(list, skb1, skb);
return 1;
}
@@ -1344,15 +1335,14 @@ static void link_handle_out_of_seq_msg(struct tipc_link *l_ptr,
return;
}
- if (tipc_link_defer_pkt(&l_ptr->oldest_deferred_in,
- &l_ptr->newest_deferred_in, buf)) {
- l_ptr->deferred_inqueue_sz++;
+ if (tipc_link_defer_pkt(&l_ptr->deferred_queue, buf)) {
l_ptr->stats.deferred_recv++;
TIPC_SKB_CB(buf)->deferred = true;
- if ((l_ptr->deferred_inqueue_sz % 16) == 1)
+ if ((skb_queue_len(&l_ptr->deferred_queue) % 16) == 1)
tipc_link_proto_xmit(l_ptr, STATE_MSG, 0, 0, 0, 0, 0);
- } else
+ } else {
l_ptr->stats.duplicates++;
+ }
}
/*
@@ -1388,8 +1378,8 @@ void tipc_link_proto_xmit(struct tipc_link *l_ptr, u32 msg_typ, int probe_msg,
if (l_ptr->next_out)
next_sent = buf_seqno(l_ptr->next_out);
msg_set_next_sent(msg, next_sent);
- if (l_ptr->oldest_deferred_in) {
- u32 rec = buf_seqno(l_ptr->oldest_deferred_in);
+ if (!skb_queue_empty(&l_ptr->deferred_queue)) {
+ u32 rec = buf_seqno(skb_peek(&l_ptr->deferred_queue));
gap = mod(rec - mod(l_ptr->next_in_no));
}
msg_set_seq_gap(msg, gap);
diff --git a/net/tipc/link.h b/net/tipc/link.h
index 96f1e1b..de7b883 100644
--- a/net/tipc/link.h
+++ b/net/tipc/link.h
@@ -124,9 +124,7 @@ struct tipc_stats {
* @last_retransmitted: sequence number of most recently retransmitted message
* @stale_count: # of identical retransmit requests made by peer
* @next_in_no: next sequence number to expect for inbound messages
- * @deferred_inqueue_sz: # of messages in inbound message queue
- * @oldest_deferred_in: ptr to first inbound message in queue
- * @newest_deferred_in: ptr to last inbound message in queue
+ * @deferred_queue: deferred queue saved OOS b'cast message received from node
* @unacked_window: # of inbound messages rx'd without ack'ing back to peer
* @next_out: ptr to first unsent outbound message in queue
* @waiting_sks: linked list of sockets waiting for link congestion to abate
@@ -178,9 +176,7 @@ struct tipc_link {
/* Reception */
u32 next_in_no;
- u32 deferred_inqueue_sz;
- struct sk_buff *oldest_deferred_in;
- struct sk_buff *newest_deferred_in;
+ struct sk_buff_head deferred_queue;
u32 unacked_window;
/* Congestion handling */
@@ -224,8 +220,7 @@ void tipc_link_bundle_rcv(struct sk_buff *buf);
void tipc_link_proto_xmit(struct tipc_link *l_ptr, u32 msg_typ, int prob,
u32 gap, u32 tolerance, u32 priority, u32 acked_mtu);
void tipc_link_push_packets(struct tipc_link *l_ptr);
-u32 tipc_link_defer_pkt(struct sk_buff **head, struct sk_buff **tail,
- struct sk_buff *buf);
+u32 tipc_link_defer_pkt(struct sk_buff_head *list, struct sk_buff *buf);
void tipc_link_set_queue_limits(struct tipc_link *l_ptr, u32 window);
void tipc_link_retransmit(struct tipc_link *l_ptr,
struct sk_buff *start, u32 retransmits);
diff --git a/net/tipc/node.c b/net/tipc/node.c
index 17b8092..69b96be 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -116,6 +116,7 @@ struct tipc_node *tipc_node_create(u32 addr)
INIT_LIST_HEAD(&n_ptr->publ_list);
INIT_LIST_HEAD(&n_ptr->conn_sks);
__skb_queue_head_init(&n_ptr->waiting_sks);
+ __skb_queue_head_init(&n_ptr->bclink.deferred_queue);
hlist_add_head_rcu(&n_ptr->hash, &node_htable[tipc_hashfn(addr)]);
@@ -381,8 +382,7 @@ static void node_lost_contact(struct tipc_node *n_ptr)
/* Flush broadcast link info associated with lost node */
if (n_ptr->bclink.recv_permitted) {
- kfree_skb_list(n_ptr->bclink.deferred_head);
- n_ptr->bclink.deferred_size = 0;
+ __skb_queue_purge(&n_ptr->bclink.deferred_queue);
if (n_ptr->bclink.reasm_buf) {
kfree_skb(n_ptr->bclink.reasm_buf);
diff --git a/net/tipc/node.h b/net/tipc/node.h
index f199451..cbe0e95 100644
--- a/net/tipc/node.h
+++ b/net/tipc/node.h
@@ -71,9 +71,7 @@ enum {
* @last_in: sequence # of last in-sequence b'cast message received from node
* @last_sent: sequence # of last b'cast message sent by node
* @oos_state: state tracker for handling OOS b'cast messages
- * @deferred_size: number of OOS b'cast messages in deferred queue
- * @deferred_head: oldest OOS b'cast message received from node
- * @deferred_tail: newest OOS b'cast message received from node
+ * @deferred_queue: deferred queue saved OOS b'cast message received from node
* @reasm_buf: broadcast reassembly queue head from node
* @recv_permitted: true if node is allowed to receive b'cast messages
*/
@@ -83,8 +81,7 @@ struct tipc_node_bclink {
u32 last_sent;
u32 oos_state;
u32 deferred_size;
- struct sk_buff *deferred_head;
- struct sk_buff *deferred_tail;
+ struct sk_buff_head deferred_queue;
struct sk_buff *reasm_buf;
bool recv_permitted;
};
--
1.7.9.5
------------------------------------------------------------------------------
Download BIRT iHub F-Type - The Free Enterprise-Grade BIRT Server
from Actuate! Instantly Supercharge Your Business Reports and Dashboards
with Interactivity, Sharing, Native Excel Exports, App Integration & more
Get technology previously reserved for billion-dollar corporations, FREE
http://pubads.g.doubleclick.net/gampad/clk?id=157005751&iu=/4140/ostg.clktrk
^ permalink raw reply related
* [PATCH net-next 08/11] tipc: use generic SKB list APIs to manage link transmission queue
From: Ying Xue @ 2014-11-26 3:41 UTC (permalink / raw)
To: davem; +Cc: jon.maloy, netdev, Paul.Gortmaker, tipc-discussion
In-Reply-To: <1416973315-6047-1-git-send-email-ying.xue@windriver.com>
Use standard SKB list APIs associated with struct sk_buff_head to
manage link transmission queue, having relevant code more clean.
Signed-off-by: Ying Xue <ying.xue@windriver.com>
Reviewed-by: Jon Maloy <jon.maloy@ericsson.com>
---
net/tipc/bcast.c | 67 +++++++++----------
net/tipc/link.c | 190 ++++++++++++++++++++++++------------------------------
net/tipc/link.h | 17 +++--
net/tipc/msg.c | 50 +++++++-------
net/tipc/msg.h | 5 +-
5 files changed, 153 insertions(+), 176 deletions(-)
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c
index 2764884..4a1a3c8 100644
--- a/net/tipc/bcast.c
+++ b/net/tipc/bcast.c
@@ -217,12 +217,13 @@ struct tipc_node *tipc_bclink_retransmit_to(void)
*/
static void bclink_retransmit_pkt(u32 after, u32 to)
{
- struct sk_buff *buf;
+ struct sk_buff *skb;
- buf = bcl->first_out;
- while (buf && less_eq(buf_seqno(buf), after))
- buf = buf->next;
- tipc_link_retransmit(bcl, buf, mod(to - after));
+ skb_queue_walk(&bcl->outqueue, skb) {
+ if (more(buf_seqno(skb), after))
+ break;
+ }
+ tipc_link_retransmit(bcl, skb, mod(to - after));
}
/**
@@ -245,14 +246,14 @@ void tipc_bclink_wakeup_users(void)
*/
void tipc_bclink_acknowledge(struct tipc_node *n_ptr, u32 acked)
{
- struct sk_buff *crs;
+ struct sk_buff *skb, *tmp;
struct sk_buff *next;
unsigned int released = 0;
tipc_bclink_lock();
/* Bail out if tx queue is empty (no clean up is required) */
- crs = bcl->first_out;
- if (!crs)
+ skb = skb_peek(&bcl->outqueue);
+ if (!skb)
goto exit;
/* Determine which messages need to be acknowledged */
@@ -271,41 +272,41 @@ void tipc_bclink_acknowledge(struct tipc_node *n_ptr, u32 acked)
* Bail out if specified sequence number does not correspond
* to a message that has been sent and not yet acknowledged
*/
- if (less(acked, buf_seqno(crs)) ||
+ if (less(acked, buf_seqno(skb)) ||
less(bcl->fsm_msg_cnt, acked) ||
less_eq(acked, n_ptr->bclink.acked))
goto exit;
}
/* Skip over packets that node has previously acknowledged */
- while (crs && less_eq(buf_seqno(crs), n_ptr->bclink.acked))
- crs = crs->next;
+ skb_queue_walk(&bcl->outqueue, skb) {
+ if (more(buf_seqno(skb), n_ptr->bclink.acked))
+ break;
+ }
/* Update packets that node is now acknowledging */
+ skb_queue_walk_from_safe(&bcl->outqueue, skb, tmp) {
+ if (more(buf_seqno(skb), acked))
+ break;
- while (crs && less_eq(buf_seqno(crs), acked)) {
- next = crs->next;
-
- if (crs != bcl->next_out)
- bcbuf_decr_acks(crs);
- else {
- bcbuf_set_acks(crs, 0);
+ next = tipc_skb_queue_next(&bcl->outqueue, skb);
+ if (skb != bcl->next_out) {
+ bcbuf_decr_acks(skb);
+ } else {
+ bcbuf_set_acks(skb, 0);
bcl->next_out = next;
bclink_set_last_sent();
}
- if (bcbuf_acks(crs) == 0) {
- bcl->first_out = next;
- bcl->out_queue_size--;
- kfree_skb(crs);
+ if (bcbuf_acks(skb) == 0) {
+ __skb_unlink(skb, &bcl->outqueue);
+ kfree_skb(skb);
released = 1;
}
- crs = next;
}
n_ptr->bclink.acked = acked;
/* Try resolving broadcast link congestion, if necessary */
-
if (unlikely(bcl->next_out)) {
tipc_link_push_packets(bcl);
bclink_set_last_sent();
@@ -327,19 +328,16 @@ void tipc_bclink_update_link_state(struct tipc_node *n_ptr, u32 last_sent)
struct sk_buff *buf;
/* Ignore "stale" link state info */
-
if (less_eq(last_sent, n_ptr->bclink.last_in))
return;
/* Update link synchronization state; quit if in sync */
-
bclink_update_last_sent(n_ptr, last_sent);
if (n_ptr->bclink.last_sent == n_ptr->bclink.last_in)
return;
/* Update out-of-sync state; quit if loss is still unconfirmed */
-
if ((++n_ptr->bclink.oos_state) == 1) {
if (n_ptr->bclink.deferred_size < (TIPC_MIN_LINK_WIN / 2))
return;
@@ -347,12 +345,10 @@ void tipc_bclink_update_link_state(struct tipc_node *n_ptr, u32 last_sent)
}
/* Don't NACK if one has been recently sent (or seen) */
-
if (n_ptr->bclink.oos_state & 0x1)
return;
/* Send NACK */
-
buf = tipc_buf_acquire(INT_H_SIZE);
if (buf) {
struct tipc_msg *msg = buf_msg(buf);
@@ -425,9 +421,11 @@ int tipc_bclink_xmit(struct sk_buff *buf)
if (likely(bclink->bcast_nodes.count)) {
rc = __tipc_link_xmit(bcl, buf);
if (likely(!rc)) {
+ u32 len = skb_queue_len(&bcl->outqueue);
+
bclink_set_last_sent();
bcl->stats.queue_sz_counts++;
- bcl->stats.accu_queue_sz += bcl->out_queue_size;
+ bcl->stats.accu_queue_sz += len;
}
bc = 1;
}
@@ -462,7 +460,6 @@ static void bclink_accept_pkt(struct tipc_node *node, u32 seqno)
* Unicast an ACK periodically, ensuring that
* all nodes in the cluster don't ACK at the same time
*/
-
if (((seqno - tipc_own_addr) % TIPC_MIN_LINK_WIN) == 0) {
tipc_link_proto_xmit(node->active_links[node->addr & 1],
STATE_MSG, 0, 0, 0, 0, 0);
@@ -484,7 +481,6 @@ void tipc_bclink_rcv(struct sk_buff *buf)
int deferred = 0;
/* Screen out unwanted broadcast messages */
-
if (msg_mc_netid(msg) != tipc_net_id)
goto exit;
@@ -497,7 +493,6 @@ void tipc_bclink_rcv(struct sk_buff *buf)
goto unlock;
/* Handle broadcast protocol message */
-
if (unlikely(msg_user(msg) == BCAST_PROTOCOL)) {
if (msg_type(msg) != STATE_MSG)
goto unlock;
@@ -518,14 +513,12 @@ void tipc_bclink_rcv(struct sk_buff *buf)
}
/* Handle in-sequence broadcast message */
-
seqno = msg_seqno(msg);
next_in = mod(node->bclink.last_in + 1);
if (likely(seqno == next_in)) {
receive:
/* Deliver message to destination */
-
if (likely(msg_isdata(msg))) {
tipc_bclink_lock();
bclink_accept_pkt(node, seqno);
@@ -574,7 +567,6 @@ receive:
buf = NULL;
/* Determine new synchronization state */
-
tipc_node_lock(node);
if (unlikely(!tipc_node_is_up(node)))
goto unlock;
@@ -594,7 +586,6 @@ receive:
goto unlock;
/* Take in-sequence message from deferred queue & deliver it */
-
buf = node->bclink.deferred_head;
node->bclink.deferred_head = buf->next;
buf->next = NULL;
@@ -603,7 +594,6 @@ receive:
}
/* Handle out-of-sequence broadcast message */
-
if (less(next_in, seqno)) {
deferred = tipc_link_defer_pkt(&node->bclink.deferred_head,
&node->bclink.deferred_tail,
@@ -963,6 +953,7 @@ int tipc_bclink_init(void)
sprintf(bcbearer->media.name, "tipc-broadcast");
spin_lock_init(&bclink->lock);
+ __skb_queue_head_init(&bcl->outqueue);
__skb_queue_head_init(&bcl->waiting_sks);
bcl->next_out_no = 1;
spin_lock_init(&bclink->node.lock);
diff --git a/net/tipc/link.c b/net/tipc/link.c
index ddee498..9e94bf9 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -171,14 +171,17 @@ int tipc_link_is_active(struct tipc_link *l_ptr)
*/
static void link_timeout(struct tipc_link *l_ptr)
{
+ struct sk_buff *skb;
+
tipc_node_lock(l_ptr->owner);
/* update counters used in statistical profiling of send traffic */
- l_ptr->stats.accu_queue_sz += l_ptr->out_queue_size;
+ l_ptr->stats.accu_queue_sz += skb_queue_len(&l_ptr->outqueue);
l_ptr->stats.queue_sz_counts++;
- if (l_ptr->first_out) {
- struct tipc_msg *msg = buf_msg(l_ptr->first_out);
+ skb = skb_peek(&l_ptr->outqueue);
+ if (skb) {
+ struct tipc_msg *msg = buf_msg(skb);
u32 length = msg_size(msg);
if ((msg_user(msg) == MSG_FRAGMENTER) &&
@@ -206,7 +209,6 @@ static void link_timeout(struct tipc_link *l_ptr)
}
/* do all other link processing performed on a periodic basis */
-
link_state_event(l_ptr, TIMEOUT_EVT);
if (l_ptr->next_out)
@@ -289,6 +291,7 @@ struct tipc_link *tipc_link_create(struct tipc_node *n_ptr,
link_init_max_pkt(l_ptr);
l_ptr->next_out_no = 1;
+ __skb_queue_head_init(&l_ptr->outqueue);
__skb_queue_head_init(&l_ptr->waiting_sks);
link_reset_statistics(l_ptr);
@@ -367,7 +370,7 @@ static bool link_schedule_user(struct tipc_link *link, u32 oport,
*/
static void link_prepare_wakeup(struct tipc_link *link)
{
- uint pend_qsz = link->out_queue_size;
+ uint pend_qsz = skb_queue_len(&link->outqueue);
struct sk_buff *skb, *tmp;
skb_queue_walk_safe(&link->waiting_sks, skb, tmp) {
@@ -380,17 +383,6 @@ static void link_prepare_wakeup(struct tipc_link *link)
}
/**
- * link_release_outqueue - purge link's outbound message queue
- * @l_ptr: pointer to link
- */
-static void link_release_outqueue(struct tipc_link *l_ptr)
-{
- kfree_skb_list(l_ptr->first_out);
- l_ptr->first_out = NULL;
- l_ptr->out_queue_size = 0;
-}
-
-/**
* tipc_link_reset_fragments - purge link's inbound message fragments queue
* @l_ptr: pointer to link
*/
@@ -407,7 +399,7 @@ void tipc_link_reset_fragments(struct tipc_link *l_ptr)
void tipc_link_purge_queues(struct tipc_link *l_ptr)
{
kfree_skb_list(l_ptr->oldest_deferred_in);
- kfree_skb_list(l_ptr->first_out);
+ __skb_queue_purge(&l_ptr->outqueue);
tipc_link_reset_fragments(l_ptr);
}
@@ -440,14 +432,12 @@ void tipc_link_reset(struct tipc_link *l_ptr)
}
/* Clean up all queues: */
- link_release_outqueue(l_ptr);
+ __skb_queue_purge(&l_ptr->outqueue);
kfree_skb_list(l_ptr->oldest_deferred_in);
if (!skb_queue_empty(&l_ptr->waiting_sks)) {
skb_queue_splice_init(&l_ptr->waiting_sks, &owner->waiting_sks);
owner->action_flags |= TIPC_WAKEUP_USERS;
}
- l_ptr->last_out = NULL;
- l_ptr->first_out = NULL;
l_ptr->next_out = NULL;
l_ptr->unacked_window = 0;
l_ptr->checkpoint = 1;
@@ -703,18 +693,17 @@ drop:
/**
* __tipc_link_xmit(): same as tipc_link_xmit, but destlink is known & locked
* @link: link to use
- * @buf: chain of buffers containing message
+ * @skb: chain of buffers containing message
* Consumes the buffer chain, except when returning -ELINKCONG
* Returns 0 if success, otherwise errno: -ELINKCONG, -EMSGSIZE (plain socket
* user data messages) or -EHOSTUNREACH (all other messages/senders)
* Only the socket functions tipc_send_stream() and tipc_send_packet() need
* to act on the return value, since they may need to do more send attempts.
*/
-int __tipc_link_xmit(struct tipc_link *link, struct sk_buff *buf)
+int __tipc_link_xmit(struct tipc_link *link, struct sk_buff *skb)
{
- struct tipc_msg *msg = buf_msg(buf);
+ struct tipc_msg *msg = buf_msg(skb);
uint psz = msg_size(msg);
- uint qsz = link->out_queue_size;
uint sndlim = link->queue_limit[0];
uint imp = tipc_msg_tot_importance(msg);
uint mtu = link->max_pkt;
@@ -722,58 +711,50 @@ int __tipc_link_xmit(struct tipc_link *link, struct sk_buff *buf)
uint seqno = link->next_out_no;
uint bc_last_in = link->owner->bclink.last_in;
struct tipc_media_addr *addr = &link->media_addr;
- struct sk_buff *next = buf->next;
+ struct sk_buff_head *outqueue = &link->outqueue;
+ struct sk_buff *next;
/* Match queue limits against msg importance: */
- if (unlikely(qsz >= link->queue_limit[imp]))
- return tipc_link_cong(link, buf);
+ if (unlikely(skb_queue_len(outqueue) >= link->queue_limit[imp]))
+ return tipc_link_cong(link, skb);
/* Has valid packet limit been used ? */
if (unlikely(psz > mtu)) {
- kfree_skb_list(buf);
+ kfree_skb_list(skb);
return -EMSGSIZE;
}
/* Prepare each packet for sending, and add to outqueue: */
- while (buf) {
- next = buf->next;
- msg = buf_msg(buf);
+ while (skb) {
+ next = skb->next;
+ msg = buf_msg(skb);
msg_set_word(msg, 2, ((ack << 16) | mod(seqno)));
msg_set_bcast_ack(msg, bc_last_in);
- if (!link->first_out) {
- link->first_out = buf;
- } else if (qsz < sndlim) {
- link->last_out->next = buf;
- } else if (tipc_msg_bundle(link->last_out, buf, mtu)) {
+ if (skb_queue_len(outqueue) < sndlim) {
+ __skb_queue_tail(outqueue, skb);
+ tipc_bearer_send(link->bearer_id, skb, addr);
+ link->next_out = NULL;
+ link->unacked_window = 0;
+ } else if (tipc_msg_bundle(outqueue, skb, mtu)) {
link->stats.sent_bundled++;
- buf = next;
- next = buf->next;
+ skb = next;
continue;
- } else if (tipc_msg_make_bundle(&buf, mtu, link->addr)) {
+ } else if (tipc_msg_make_bundle(outqueue, skb, mtu,
+ link->addr)) {
link->stats.sent_bundled++;
link->stats.sent_bundles++;
- link->last_out->next = buf;
if (!link->next_out)
- link->next_out = buf;
+ link->next_out = skb_peek_tail(outqueue);
} else {
- link->last_out->next = buf;
+ __skb_queue_tail(outqueue, skb);
if (!link->next_out)
- link->next_out = buf;
- }
-
- /* Send packet if possible: */
- if (likely(++qsz <= sndlim)) {
- tipc_bearer_send(link->bearer_id, buf, addr);
- link->next_out = next;
- link->unacked_window = 0;
+ link->next_out = skb;
}
seqno++;
- link->last_out = buf;
- buf = next;
+ skb = next;
}
link->next_out_no = seqno;
- link->out_queue_size = qsz;
return 0;
}
@@ -851,6 +832,14 @@ static void tipc_link_sync_rcv(struct tipc_node *n, struct sk_buff *buf)
kfree_skb(buf);
}
+struct sk_buff *tipc_skb_queue_next(const struct sk_buff_head *list,
+ const struct sk_buff *skb)
+{
+ if (skb_queue_is_last(list, skb))
+ return NULL;
+ return skb->next;
+}
+
/*
* tipc_link_push_packets - push unsent packets to bearer
*
@@ -861,15 +850,15 @@ static void tipc_link_sync_rcv(struct tipc_node *n, struct sk_buff *buf)
*/
void tipc_link_push_packets(struct tipc_link *l_ptr)
{
- struct sk_buff *skb;
+ struct sk_buff_head *outqueue = &l_ptr->outqueue;
+ struct sk_buff *skb = l_ptr->next_out;
struct tipc_msg *msg;
u32 next, first;
- while (l_ptr->next_out) {
- skb = l_ptr->next_out;
+ skb_queue_walk_from(outqueue, skb) {
msg = buf_msg(skb);
next = msg_seqno(msg);
- first = buf_seqno(l_ptr->first_out);
+ first = buf_seqno(skb_peek(outqueue));
if (mod(next - first) < l_ptr->queue_limit[0]) {
msg_set_ack(msg, mod(l_ptr->next_in_no - 1));
@@ -878,7 +867,7 @@ void tipc_link_push_packets(struct tipc_link *l_ptr)
TIPC_SKB_CB(skb)->bundling = false;
tipc_bearer_send(l_ptr->bearer_id, skb,
&l_ptr->media_addr);
- l_ptr->next_out = skb->next;
+ l_ptr->next_out = tipc_skb_queue_next(outqueue, skb);
} else {
break;
}
@@ -946,20 +935,20 @@ static void link_retransmit_failure(struct tipc_link *l_ptr,
}
}
-void tipc_link_retransmit(struct tipc_link *l_ptr, struct sk_buff *buf,
+void tipc_link_retransmit(struct tipc_link *l_ptr, struct sk_buff *skb,
u32 retransmits)
{
struct tipc_msg *msg;
- if (!buf)
+ if (!skb)
return;
- msg = buf_msg(buf);
+ msg = buf_msg(skb);
/* Detect repeated retransmit failures */
if (l_ptr->last_retransmitted == msg_seqno(msg)) {
if (++l_ptr->stale_count > 100) {
- link_retransmit_failure(l_ptr, buf);
+ link_retransmit_failure(l_ptr, skb);
return;
}
} else {
@@ -967,12 +956,13 @@ void tipc_link_retransmit(struct tipc_link *l_ptr, struct sk_buff *buf,
l_ptr->stale_count = 1;
}
- while (retransmits && (buf != l_ptr->next_out) && buf) {
- msg = buf_msg(buf);
+ skb_queue_walk_from(&l_ptr->outqueue, skb) {
+ if (!retransmits || skb == l_ptr->next_out)
+ break;
+ msg = buf_msg(skb);
msg_set_ack(msg, mod(l_ptr->next_in_no - 1));
msg_set_bcast_ack(msg, l_ptr->owner->bclink.last_in);
- tipc_bearer_send(l_ptr->bearer_id, buf, &l_ptr->media_addr);
- buf = buf->next;
+ tipc_bearer_send(l_ptr->bearer_id, skb, &l_ptr->media_addr);
retransmits--;
l_ptr->stats.retransmitted++;
}
@@ -1067,12 +1057,12 @@ void tipc_rcv(struct sk_buff *head, struct tipc_bearer *b_ptr)
while (head) {
struct tipc_node *n_ptr;
struct tipc_link *l_ptr;
- struct sk_buff *crs;
struct sk_buff *buf = head;
+ struct sk_buff *skb1, *tmp;
struct tipc_msg *msg;
u32 seq_no;
u32 ackd;
- u32 released = 0;
+ u32 released;
head = head->next;
buf->next = NULL;
@@ -1131,17 +1121,14 @@ void tipc_rcv(struct sk_buff *head, struct tipc_bearer *b_ptr)
if (n_ptr->bclink.recv_permitted)
tipc_bclink_acknowledge(n_ptr, msg_bcast_ack(msg));
- crs = l_ptr->first_out;
- while ((crs != l_ptr->next_out) &&
- less_eq(buf_seqno(crs), ackd)) {
- struct sk_buff *next = crs->next;
- kfree_skb(crs);
- crs = next;
- released++;
- }
- if (released) {
- l_ptr->first_out = crs;
- l_ptr->out_queue_size -= released;
+ released = 0;
+ skb_queue_walk_safe(&l_ptr->outqueue, skb1, tmp) {
+ if (skb1 == l_ptr->next_out ||
+ more(buf_seqno(skb1), ackd))
+ break;
+ __skb_unlink(skb1, &l_ptr->outqueue);
+ kfree_skb(skb1);
+ released = 1;
}
/* Try sending any messages link endpoint has pending */
@@ -1590,7 +1577,7 @@ static void tipc_link_proto_rcv(struct tipc_link *l_ptr, struct sk_buff *buf)
}
if (msg_seq_gap(msg)) {
l_ptr->stats.recv_nacks++;
- tipc_link_retransmit(l_ptr, l_ptr->first_out,
+ tipc_link_retransmit(l_ptr, skb_peek(&l_ptr->outqueue),
msg_seq_gap(msg));
}
break;
@@ -1637,10 +1624,10 @@ static void tipc_link_tunnel_xmit(struct tipc_link *l_ptr,
*/
void tipc_link_failover_send_queue(struct tipc_link *l_ptr)
{
- u32 msgcount = l_ptr->out_queue_size;
- struct sk_buff *crs = l_ptr->first_out;
+ u32 msgcount = skb_queue_len(&l_ptr->outqueue);
struct tipc_link *tunnel = l_ptr->owner->active_links[0];
struct tipc_msg tunnel_hdr;
+ struct sk_buff *skb;
int split_bundles;
if (!tunnel)
@@ -1651,14 +1638,12 @@ void tipc_link_failover_send_queue(struct tipc_link *l_ptr)
msg_set_bearer_id(&tunnel_hdr, l_ptr->peer_bearer_id);
msg_set_msgcnt(&tunnel_hdr, msgcount);
- if (!l_ptr->first_out) {
- struct sk_buff *buf;
-
- buf = tipc_buf_acquire(INT_H_SIZE);
- if (buf) {
- skb_copy_to_linear_data(buf, &tunnel_hdr, INT_H_SIZE);
+ if (skb_queue_empty(&l_ptr->outqueue)) {
+ skb = tipc_buf_acquire(INT_H_SIZE);
+ if (skb) {
+ skb_copy_to_linear_data(skb, &tunnel_hdr, INT_H_SIZE);
msg_set_size(&tunnel_hdr, INT_H_SIZE);
- __tipc_link_xmit(tunnel, buf);
+ __tipc_link_xmit(tunnel, skb);
} else {
pr_warn("%sunable to send changeover msg\n",
link_co_err);
@@ -1669,8 +1654,8 @@ void tipc_link_failover_send_queue(struct tipc_link *l_ptr)
split_bundles = (l_ptr->owner->active_links[0] !=
l_ptr->owner->active_links[1]);
- while (crs) {
- struct tipc_msg *msg = buf_msg(crs);
+ skb_queue_walk(&l_ptr->outqueue, skb) {
+ struct tipc_msg *msg = buf_msg(skb);
if ((msg_user(msg) == MSG_BUNDLER) && split_bundles) {
struct tipc_msg *m = msg_get_wrapped(msg);
@@ -1688,7 +1673,6 @@ void tipc_link_failover_send_queue(struct tipc_link *l_ptr)
tipc_link_tunnel_xmit(l_ptr, &tunnel_hdr, msg,
msg_link_selector(msg));
}
- crs = crs->next;
}
}
@@ -1704,17 +1688,16 @@ void tipc_link_failover_send_queue(struct tipc_link *l_ptr)
void tipc_link_dup_queue_xmit(struct tipc_link *l_ptr,
struct tipc_link *tunnel)
{
- struct sk_buff *iter;
+ struct sk_buff *skb;
struct tipc_msg tunnel_hdr;
tipc_msg_init(&tunnel_hdr, CHANGEOVER_PROTOCOL,
DUPLICATE_MSG, INT_H_SIZE, l_ptr->addr);
- msg_set_msgcnt(&tunnel_hdr, l_ptr->out_queue_size);
+ msg_set_msgcnt(&tunnel_hdr, skb_queue_len(&l_ptr->outqueue));
msg_set_bearer_id(&tunnel_hdr, l_ptr->peer_bearer_id);
- iter = l_ptr->first_out;
- while (iter) {
- struct sk_buff *outbuf;
- struct tipc_msg *msg = buf_msg(iter);
+ skb_queue_walk(&l_ptr->outqueue, skb) {
+ struct sk_buff *outskb;
+ struct tipc_msg *msg = buf_msg(skb);
u32 length = msg_size(msg);
if (msg_user(msg) == MSG_BUNDLER)
@@ -1722,19 +1705,18 @@ void tipc_link_dup_queue_xmit(struct tipc_link *l_ptr,
msg_set_ack(msg, mod(l_ptr->next_in_no - 1)); /* Update */
msg_set_bcast_ack(msg, l_ptr->owner->bclink.last_in);
msg_set_size(&tunnel_hdr, length + INT_H_SIZE);
- outbuf = tipc_buf_acquire(length + INT_H_SIZE);
- if (outbuf == NULL) {
+ outskb = tipc_buf_acquire(length + INT_H_SIZE);
+ if (outskb == NULL) {
pr_warn("%sunable to send duplicate msg\n",
link_co_err);
return;
}
- skb_copy_to_linear_data(outbuf, &tunnel_hdr, INT_H_SIZE);
- skb_copy_to_linear_data_offset(outbuf, INT_H_SIZE, iter->data,
+ skb_copy_to_linear_data(outskb, &tunnel_hdr, INT_H_SIZE);
+ skb_copy_to_linear_data_offset(outskb, INT_H_SIZE, skb->data,
length);
- __tipc_link_xmit(tunnel, outbuf);
+ __tipc_link_xmit(tunnel, outskb);
if (!tipc_link_is_up(l_ptr))
return;
- iter = iter->next;
}
}
diff --git a/net/tipc/link.h b/net/tipc/link.h
index 7711234..96f1e1b 100644
--- a/net/tipc/link.h
+++ b/net/tipc/link.h
@@ -119,9 +119,7 @@ struct tipc_stats {
* @max_pkt: current maximum packet size for this link
* @max_pkt_target: desired maximum packet size for this link
* @max_pkt_probes: # of probes based on current (max_pkt, max_pkt_target)
- * @out_queue_size: # of messages in outbound message queue
- * @first_out: ptr to first outbound message in queue
- * @last_out: ptr to last outbound message in queue
+ * @outqueue: outbound message queue
* @next_out_no: next sequence number to use for outbound messages
* @last_retransmitted: sequence number of most recently retransmitted message
* @stale_count: # of identical retransmit requests made by peer
@@ -173,9 +171,7 @@ struct tipc_link {
u32 max_pkt_probes;
/* Sending */
- u32 out_queue_size;
- struct sk_buff *first_out;
- struct sk_buff *last_out;
+ struct sk_buff_head outqueue;
u32 next_out_no;
u32 last_retransmitted;
u32 stale_count;
@@ -233,6 +229,8 @@ u32 tipc_link_defer_pkt(struct sk_buff **head, struct sk_buff **tail,
void tipc_link_set_queue_limits(struct tipc_link *l_ptr, u32 window);
void tipc_link_retransmit(struct tipc_link *l_ptr,
struct sk_buff *start, u32 retransmits);
+struct sk_buff *tipc_skb_queue_next(const struct sk_buff_head *list,
+ const struct sk_buff *skb);
int tipc_nl_link_dump(struct sk_buff *skb, struct netlink_callback *cb);
int tipc_nl_link_get(struct sk_buff *skb, struct genl_info *info);
@@ -258,6 +256,11 @@ static inline int less_eq(u32 left, u32 right)
return mod(right - left) < 32768u;
}
+static inline int more(u32 left, u32 right)
+{
+ return !less_eq(left, right);
+}
+
static inline int less(u32 left, u32 right)
{
return less_eq(left, right) && (mod(right) != mod(left));
@@ -294,7 +297,7 @@ static inline int link_reset_reset(struct tipc_link *l_ptr)
static inline int link_congested(struct tipc_link *l_ptr)
{
- return l_ptr->out_queue_size >= l_ptr->queue_limit[0];
+ return skb_queue_len(&l_ptr->outqueue) >= l_ptr->queue_limit[0];
}
#endif
diff --git a/net/tipc/msg.c b/net/tipc/msg.c
index 94db392..ce7514a 100644
--- a/net/tipc/msg.c
+++ b/net/tipc/msg.c
@@ -265,16 +265,17 @@ error:
/**
* tipc_msg_bundle(): Append contents of a buffer to tail of an existing one
- * @bbuf: the existing buffer ("bundle")
- * @buf: buffer to be appended
+ * @list: the buffer chain of the existing buffer ("bundle")
+ * @skb: buffer to be appended
* @mtu: max allowable size for the bundle buffer
* Consumes buffer if successful
* Returns true if bundling could be performed, otherwise false
*/
-bool tipc_msg_bundle(struct sk_buff *bbuf, struct sk_buff *buf, u32 mtu)
+bool tipc_msg_bundle(struct sk_buff_head *list, struct sk_buff *skb, u32 mtu)
{
- struct tipc_msg *bmsg = buf_msg(bbuf);
- struct tipc_msg *msg = buf_msg(buf);
+ struct sk_buff *bskb = skb_peek_tail(list);
+ struct tipc_msg *bmsg = buf_msg(bskb);
+ struct tipc_msg *msg = buf_msg(skb);
unsigned int bsz = msg_size(bmsg);
unsigned int msz = msg_size(msg);
u32 start = align(bsz);
@@ -289,35 +290,36 @@ bool tipc_msg_bundle(struct sk_buff *bbuf, struct sk_buff *buf, u32 mtu)
return false;
if (likely(msg_user(bmsg) != MSG_BUNDLER))
return false;
- if (likely(!TIPC_SKB_CB(bbuf)->bundling))
+ if (likely(!TIPC_SKB_CB(bskb)->bundling))
return false;
- if (unlikely(skb_tailroom(bbuf) < (pad + msz)))
+ if (unlikely(skb_tailroom(bskb) < (pad + msz)))
return false;
if (unlikely(max < (start + msz)))
return false;
- skb_put(bbuf, pad + msz);
- skb_copy_to_linear_data_offset(bbuf, start, buf->data, msz);
+ skb_put(bskb, pad + msz);
+ skb_copy_to_linear_data_offset(bskb, start, skb->data, msz);
msg_set_size(bmsg, start + msz);
msg_set_msgcnt(bmsg, msg_msgcnt(bmsg) + 1);
- bbuf->next = buf->next;
- kfree_skb(buf);
+ kfree_skb(skb);
return true;
}
/**
* tipc_msg_make_bundle(): Create bundle buf and append message to its tail
- * @buf: buffer to be appended and replaced
- * @mtu: max allowable size for the bundle buffer, inclusive header
+ * @list: the buffer chain
+ * @skb: buffer to be appended and replaced
+ * @mtu: max allowable size for the bundle buffer, inclusive header
* @dnode: destination node for message. (Not always present in header)
* Replaces buffer if successful
* Returns true if success, otherwise false
*/
-bool tipc_msg_make_bundle(struct sk_buff **buf, u32 mtu, u32 dnode)
+bool tipc_msg_make_bundle(struct sk_buff_head *list, struct sk_buff *skb,
+ u32 mtu, u32 dnode)
{
- struct sk_buff *bbuf;
+ struct sk_buff *bskb;
struct tipc_msg *bmsg;
- struct tipc_msg *msg = buf_msg(*buf);
+ struct tipc_msg *msg = buf_msg(skb);
u32 msz = msg_size(msg);
u32 max = mtu - INT_H_SIZE;
@@ -330,21 +332,19 @@ bool tipc_msg_make_bundle(struct sk_buff **buf, u32 mtu, u32 dnode)
if (msz > (max / 2))
return false;
- bbuf = tipc_buf_acquire(max);
- if (!bbuf)
+ bskb = tipc_buf_acquire(max);
+ if (!bskb)
return false;
- skb_trim(bbuf, INT_H_SIZE);
- bmsg = buf_msg(bbuf);
+ skb_trim(bskb, INT_H_SIZE);
+ bmsg = buf_msg(bskb);
tipc_msg_init(bmsg, MSG_BUNDLER, 0, INT_H_SIZE, dnode);
msg_set_seqno(bmsg, msg_seqno(msg));
msg_set_ack(bmsg, msg_ack(msg));
msg_set_bcast_ack(bmsg, msg_bcast_ack(msg));
- bbuf->next = (*buf)->next;
- TIPC_SKB_CB(bbuf)->bundling = true;
- tipc_msg_bundle(bbuf, *buf, mtu);
- *buf = bbuf;
- return true;
+ TIPC_SKB_CB(bskb)->bundling = true;
+ __skb_queue_tail(list, bskb);
+ return tipc_msg_bundle(list, skb, mtu);
}
/**
diff --git a/net/tipc/msg.h b/net/tipc/msg.h
index 8ca874d..53e425f 100644
--- a/net/tipc/msg.h
+++ b/net/tipc/msg.h
@@ -734,9 +734,10 @@ struct sk_buff *tipc_msg_create(uint user, uint type, uint hdr_sz,
int tipc_buf_append(struct sk_buff **headbuf, struct sk_buff **buf);
-bool tipc_msg_bundle(struct sk_buff *bbuf, struct sk_buff *buf, u32 mtu);
+bool tipc_msg_bundle(struct sk_buff_head *list, struct sk_buff *skb, u32 mtu);
-bool tipc_msg_make_bundle(struct sk_buff **buf, u32 mtu, u32 dnode);
+bool tipc_msg_make_bundle(struct sk_buff_head *list, struct sk_buff *skb,
+ u32 mtu, u32 dnode);
int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m,
int offset, int dsz, int mtu , struct sk_buff **chain);
--
1.7.9.5
------------------------------------------------------------------------------
Download BIRT iHub F-Type - The Free Enterprise-Grade BIRT Server
from Actuate! Instantly Supercharge Your Business Reports and Dashboards
with Interactivity, Sharing, Native Excel Exports, App Integration & more
Get technology previously reserved for billion-dollar corporations, FREE
http://pubads.g.doubleclick.net/gampad/clk?id=157005751&iu=/4140/ostg.clktrk
^ permalink raw reply related
* [PATCH net-next 07/11] tipc: use skb_queue_walk_safe marco to simplify link_prepare_wakeup routine
From: Ying Xue @ 2014-11-26 3:41 UTC (permalink / raw)
To: davem; +Cc: jon.maloy, netdev, Paul.Gortmaker, tipc-discussion
In-Reply-To: <1416973315-6047-1-git-send-email-ying.xue@windriver.com>
Signed-off-by: Ying Xue <ying.xue@windriver.com>
Reviewed-by: Jon Maloy <jon.maloy@ericsson.com>
---
net/tipc/link.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/net/tipc/link.c b/net/tipc/link.c
index 8eb885e..ddee498 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -367,15 +367,15 @@ static bool link_schedule_user(struct tipc_link *link, u32 oport,
*/
static void link_prepare_wakeup(struct tipc_link *link)
{
- struct sk_buff_head *wq = &link->waiting_sks;
- struct sk_buff *buf;
uint pend_qsz = link->out_queue_size;
+ struct sk_buff *skb, *tmp;
- for (buf = skb_peek(wq); buf; buf = skb_peek(wq)) {
- if (pend_qsz >= link->queue_limit[TIPC_SKB_CB(buf)->chain_imp])
+ skb_queue_walk_safe(&link->waiting_sks, skb, tmp) {
+ if (pend_qsz >= link->queue_limit[TIPC_SKB_CB(skb)->chain_imp])
break;
- pend_qsz += TIPC_SKB_CB(buf)->chain_sz;
- __skb_queue_tail(&link->owner->waiting_sks, __skb_dequeue(wq));
+ pend_qsz += TIPC_SKB_CB(skb)->chain_sz;
+ __skb_unlink(skb, &link->waiting_sks);
+ __skb_queue_tail(&link->owner->waiting_sks, skb);
}
}
--
1.7.9.5
------------------------------------------------------------------------------
Download BIRT iHub F-Type - The Free Enterprise-Grade BIRT Server
from Actuate! Instantly Supercharge Your Business Reports and Dashboards
with Interactivity, Sharing, Native Excel Exports, App Integration & more
Get technology previously reserved for billion-dollar corporations, FREE
http://pubads.g.doubleclick.net/gampad/clk?id=157005751&iu=/4140/ostg.clktrk
^ permalink raw reply related
* [PATCH net-next 06/11] tipc: remove unused between routine
From: Ying Xue @ 2014-11-26 3:41 UTC (permalink / raw)
To: davem; +Cc: jon.maloy, netdev, Paul.Gortmaker, tipc-discussion
In-Reply-To: <1416973315-6047-1-git-send-email-ying.xue@windriver.com>
Signed-off-by: Ying Xue <ying.xue@windriver.com>
Reviewed-by: Jon Maloy <jon.maloy@ericsson.com>
---
net/tipc/link.h | 9 ---------
1 file changed, 9 deletions(-)
diff --git a/net/tipc/link.h b/net/tipc/link.h
index 1681076..7711234 100644
--- a/net/tipc/link.h
+++ b/net/tipc/link.h
@@ -253,15 +253,6 @@ static inline u32 mod(u32 x)
return x & 0xffffu;
}
-static inline int between(u32 lower, u32 upper, u32 n)
-{
- if ((lower < n) && (n < upper))
- return 1;
- if ((upper < lower) && ((n > lower) || (n < upper)))
- return 1;
- return 0;
-}
-
static inline int less_eq(u32 left, u32 right)
{
return mod(right - left) < 32768u;
--
1.7.9.5
------------------------------------------------------------------------------
Download BIRT iHub F-Type - The Free Enterprise-Grade BIRT Server
from Actuate! Instantly Supercharge Your Business Reports and Dashboards
with Interactivity, Sharing, Native Excel Exports, App Integration & more
Get technology previously reserved for billion-dollar corporations, FREE
http://pubads.g.doubleclick.net/gampad/clk?id=157005751&iu=/4140/ostg.clktrk
^ permalink raw reply related
* [PATCH net-next 05/11] tipc: eliminate two pseudo message types of BUNDLE_OPEN and BUNDLE_CLOSED
From: Ying Xue @ 2014-11-26 3:41 UTC (permalink / raw)
To: davem; +Cc: jon.maloy, netdev, Paul.Gortmaker, tipc-discussion
In-Reply-To: <1416973315-6047-1-git-send-email-ying.xue@windriver.com>
The pseudo message types of BUNDLE_CLOSED as well as BUNDLE_OPEN are
used to flag whether or not more messages can be bundled into a data
packet in the outgoing transmission queue. Obviously, no more messages
can be appended after the packet has been sent and is waiting to be
acknowledged and deleted. These message types do in reality represent
a send-side local implementation flag, and are not defined as part of
the protocol. It is therefore safe to move it to to where it belongs,
that is, the control area (TIPC_SKB_CB) of the buffer.
Signed-off-by: Ying Xue <ying.xue@windriver.com>
Reviewed-by: Jon Maloy <jon.maloy@ericsson.com>
---
net/tipc/core.h | 1 +
net/tipc/link.c | 2 +-
net/tipc/msg.c | 5 +++--
net/tipc/msg.h | 5 -----
4 files changed, 5 insertions(+), 8 deletions(-)
diff --git a/net/tipc/core.h b/net/tipc/core.h
index b578b10..8460213 100644
--- a/net/tipc/core.h
+++ b/net/tipc/core.h
@@ -192,6 +192,7 @@ struct tipc_skb_cb {
struct sk_buff *tail;
bool deferred;
bool wakeup_pending;
+ bool bundling;
u16 chain_sz;
u16 chain_imp;
};
diff --git a/net/tipc/link.c b/net/tipc/link.c
index 470f053..8eb885e 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -875,7 +875,7 @@ void tipc_link_push_packets(struct tipc_link *l_ptr)
msg_set_ack(msg, mod(l_ptr->next_in_no - 1));
msg_set_bcast_ack(msg, l_ptr->owner->bclink.last_in);
if (msg_user(msg) == MSG_BUNDLER)
- msg_set_type(msg, BUNDLE_CLOSED);
+ TIPC_SKB_CB(skb)->bundling = false;
tipc_bearer_send(l_ptr->bearer_id, skb,
&l_ptr->media_addr);
l_ptr->next_out = skb->next;
diff --git a/net/tipc/msg.c b/net/tipc/msg.c
index 9155496..94db392 100644
--- a/net/tipc/msg.c
+++ b/net/tipc/msg.c
@@ -289,7 +289,7 @@ bool tipc_msg_bundle(struct sk_buff *bbuf, struct sk_buff *buf, u32 mtu)
return false;
if (likely(msg_user(bmsg) != MSG_BUNDLER))
return false;
- if (likely(msg_type(bmsg) != BUNDLE_OPEN))
+ if (likely(!TIPC_SKB_CB(bbuf)->bundling))
return false;
if (unlikely(skb_tailroom(bbuf) < (pad + msz)))
return false;
@@ -336,11 +336,12 @@ bool tipc_msg_make_bundle(struct sk_buff **buf, u32 mtu, u32 dnode)
skb_trim(bbuf, INT_H_SIZE);
bmsg = buf_msg(bbuf);
- tipc_msg_init(bmsg, MSG_BUNDLER, BUNDLE_OPEN, INT_H_SIZE, dnode);
+ tipc_msg_init(bmsg, MSG_BUNDLER, 0, INT_H_SIZE, dnode);
msg_set_seqno(bmsg, msg_seqno(msg));
msg_set_ack(bmsg, msg_ack(msg));
msg_set_bcast_ack(bmsg, msg_bcast_ack(msg));
bbuf->next = (*buf)->next;
+ TIPC_SKB_CB(bbuf)->bundling = true;
tipc_msg_bundle(bbuf, *buf, mtu);
*buf = bbuf;
return true;
diff --git a/net/tipc/msg.h b/net/tipc/msg.h
index d7d2ba2..8ca874d 100644
--- a/net/tipc/msg.h
+++ b/net/tipc/msg.h
@@ -464,11 +464,6 @@ static inline struct tipc_msg *msg_get_wrapped(struct tipc_msg *m)
#define FRAGMENT 1
#define LAST_FRAGMENT 2
-/* Bundling protocol message types
- */
-#define BUNDLE_OPEN 0
-#define BUNDLE_CLOSED 1
-
/*
* Link management protocol message types
*/
--
1.7.9.5
------------------------------------------------------------------------------
Download BIRT iHub F-Type - The Free Enterprise-Grade BIRT Server
from Actuate! Instantly Supercharge Your Business Reports and Dashboards
with Interactivity, Sharing, Native Excel Exports, App Integration & more
Get technology previously reserved for billion-dollar corporations, FREE
http://pubads.g.doubleclick.net/gampad/clk?id=157005751&iu=/4140/ostg.clktrk
^ permalink raw reply related
* [PATCH net-next 04/11] tipc: clean up the process of link pushing packets
From: Ying Xue @ 2014-11-26 3:41 UTC (permalink / raw)
To: davem; +Cc: jon.maloy, netdev, Paul.Gortmaker, tipc-discussion
In-Reply-To: <1416973315-6047-1-git-send-email-ying.xue@windriver.com>
In original tipc_link_push_packet(), it pushes messages from protocol
message queue, retransmission queue and next_out queue. But as the two
first queues are removed, we can simplify its relevant code through
deleting tipc_link_push_queue().
Signed-off-by: Ying Xue <ying.xue@windriver.com>
Reviewed-by: Jon Maloy <jon.maloy@ericsson.com>
---
net/tipc/bcast.c | 2 +-
net/tipc/link.c | 62 +++++++++++++++++++-----------------------------------
net/tipc/link.h | 2 +-
3 files changed, 24 insertions(+), 42 deletions(-)
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c
index 556b26a..2764884 100644
--- a/net/tipc/bcast.c
+++ b/net/tipc/bcast.c
@@ -307,7 +307,7 @@ void tipc_bclink_acknowledge(struct tipc_node *n_ptr, u32 acked)
/* Try resolving broadcast link congestion, if necessary */
if (unlikely(bcl->next_out)) {
- tipc_link_push_queue(bcl);
+ tipc_link_push_packets(bcl);
bclink_set_last_sent();
}
if (unlikely(released && !skb_queue_empty(&bcl->waiting_sks)))
diff --git a/net/tipc/link.c b/net/tipc/link.c
index 4b7cbfd..470f053 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -149,18 +149,6 @@ static void link_init_max_pkt(struct tipc_link *l_ptr)
l_ptr->max_pkt_probes = 0;
}
-static u32 link_next_sent(struct tipc_link *l_ptr)
-{
- if (l_ptr->next_out)
- return buf_seqno(l_ptr->next_out);
- return mod(l_ptr->next_out_no);
-}
-
-static u32 link_last_sent(struct tipc_link *l_ptr)
-{
- return mod(link_next_sent(l_ptr) - 1);
-}
-
/*
* Simple non-static link routines (i.e. referenced outside this file)
*/
@@ -222,7 +210,7 @@ static void link_timeout(struct tipc_link *l_ptr)
link_state_event(l_ptr, TIMEOUT_EVT);
if (l_ptr->next_out)
- tipc_link_push_queue(l_ptr);
+ tipc_link_push_packets(l_ptr);
tipc_node_unlock(l_ptr->owner);
}
@@ -864,43 +852,37 @@ static void tipc_link_sync_rcv(struct tipc_node *n, struct sk_buff *buf)
}
/*
- * tipc_link_push_packet: Push one unsent packet to the media
+ * tipc_link_push_packets - push unsent packets to bearer
+ *
+ * Push out the unsent messages of a link where congestion
+ * has abated. Node is locked.
+ *
+ * Called with node locked
*/
-static u32 tipc_link_push_packet(struct tipc_link *l_ptr)
+void tipc_link_push_packets(struct tipc_link *l_ptr)
{
- struct sk_buff *buf = l_ptr->next_out;
+ struct sk_buff *skb;
+ struct tipc_msg *msg;
+ u32 next, first;
- /* Send one deferred data message, if send window not full: */
- if (buf) {
- struct tipc_msg *msg = buf_msg(buf);
- u32 next = msg_seqno(msg);
- u32 first = buf_seqno(l_ptr->first_out);
+ while (l_ptr->next_out) {
+ skb = l_ptr->next_out;
+ msg = buf_msg(skb);
+ next = msg_seqno(msg);
+ first = buf_seqno(l_ptr->first_out);
if (mod(next - first) < l_ptr->queue_limit[0]) {
msg_set_ack(msg, mod(l_ptr->next_in_no - 1));
msg_set_bcast_ack(msg, l_ptr->owner->bclink.last_in);
- tipc_bearer_send(l_ptr->bearer_id, buf,
- &l_ptr->media_addr);
if (msg_user(msg) == MSG_BUNDLER)
msg_set_type(msg, BUNDLE_CLOSED);
- l_ptr->next_out = buf->next;
- return 0;
+ tipc_bearer_send(l_ptr->bearer_id, skb,
+ &l_ptr->media_addr);
+ l_ptr->next_out = skb->next;
+ } else {
+ break;
}
}
- return 1;
-}
-
-/*
- * push_queue(): push out the unsent messages of a link where
- * congestion has abated. Node is locked
- */
-void tipc_link_push_queue(struct tipc_link *l_ptr)
-{
- u32 res;
-
- do {
- res = tipc_link_push_packet(l_ptr);
- } while (!res);
}
void tipc_link_reset_all(struct tipc_node *node)
@@ -1164,7 +1146,7 @@ void tipc_rcv(struct sk_buff *head, struct tipc_bearer *b_ptr)
/* Try sending any messages link endpoint has pending */
if (unlikely(l_ptr->next_out))
- tipc_link_push_queue(l_ptr);
+ tipc_link_push_packets(l_ptr);
if (released && !skb_queue_empty(&l_ptr->waiting_sks)) {
link_prepare_wakeup(l_ptr);
diff --git a/net/tipc/link.h b/net/tipc/link.h
index cc816aa..1681076 100644
--- a/net/tipc/link.h
+++ b/net/tipc/link.h
@@ -227,7 +227,7 @@ u32 tipc_link_get_max_pkt(u32 dest, u32 selector);
void tipc_link_bundle_rcv(struct sk_buff *buf);
void tipc_link_proto_xmit(struct tipc_link *l_ptr, u32 msg_typ, int prob,
u32 gap, u32 tolerance, u32 priority, u32 acked_mtu);
-void tipc_link_push_queue(struct tipc_link *l_ptr);
+void tipc_link_push_packets(struct tipc_link *l_ptr);
u32 tipc_link_defer_pkt(struct sk_buff **head, struct sk_buff **tail,
struct sk_buff *buf);
void tipc_link_set_queue_limits(struct tipc_link *l_ptr, u32 window);
--
1.7.9.5
------------------------------------------------------------------------------
Download BIRT iHub F-Type - The Free Enterprise-Grade BIRT Server
from Actuate! Instantly Supercharge Your Business Reports and Dashboards
with Interactivity, Sharing, Native Excel Exports, App Integration & more
Get technology previously reserved for billion-dollar corporations, FREE
http://pubads.g.doubleclick.net/gampad/clk?id=157005751&iu=/4140/ostg.clktrk
^ permalink raw reply related
* [PATCH net-next 03/11] tipc: remove retransmission queue
From: Ying Xue @ 2014-11-26 3:41 UTC (permalink / raw)
To: davem; +Cc: jon.maloy, netdev, Paul.Gortmaker, tipc-discussion
In-Reply-To: <1416973315-6047-1-git-send-email-ying.xue@windriver.com>
TIPC retransmission queue is intended to record which messages
should be retransmitted when bearer is not congested. However,
as the retransmission queue becomes useless with the removal of
bearer congestion mechanism, it should be removed.
Signed-off-by: Ying Xue <ying.xue@windriver.com>
Reviewed-by: Jon Maloy <jon.maloy@ericsson.com>
---
net/tipc/link.c | 35 +----------------------------------
net/tipc/link.h | 4 ----
2 files changed, 1 insertion(+), 38 deletions(-)
diff --git a/net/tipc/link.c b/net/tipc/link.c
index 450ed0c..4b7cbfd 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -458,8 +458,6 @@ void tipc_link_reset(struct tipc_link *l_ptr)
skb_queue_splice_init(&l_ptr->waiting_sks, &owner->waiting_sks);
owner->action_flags |= TIPC_WAKEUP_USERS;
}
- l_ptr->retransm_queue_head = 0;
- l_ptr->retransm_queue_size = 0;
l_ptr->last_out = NULL;
l_ptr->first_out = NULL;
l_ptr->next_out = NULL;
@@ -870,38 +868,9 @@ static void tipc_link_sync_rcv(struct tipc_node *n, struct sk_buff *buf)
*/
static u32 tipc_link_push_packet(struct tipc_link *l_ptr)
{
- struct sk_buff *buf = l_ptr->first_out;
- u32 r_q_size = l_ptr->retransm_queue_size;
- u32 r_q_head = l_ptr->retransm_queue_head;
-
- /* Step to position where retransmission failed, if any, */
- /* consider that buffers may have been released in meantime */
- if (r_q_size && buf) {
- u32 last = lesser(mod(r_q_head + r_q_size),
- link_last_sent(l_ptr));
- u32 first = buf_seqno(buf);
-
- while (buf && less(first, r_q_head)) {
- first = mod(first + 1);
- buf = buf->next;
- }
- l_ptr->retransm_queue_head = r_q_head = first;
- l_ptr->retransm_queue_size = r_q_size = mod(last - first);
- }
-
- /* Continue retransmission now, if there is anything: */
- if (r_q_size && buf) {
- msg_set_ack(buf_msg(buf), mod(l_ptr->next_in_no - 1));
- msg_set_bcast_ack(buf_msg(buf), l_ptr->owner->bclink.last_in);
- tipc_bearer_send(l_ptr->bearer_id, buf, &l_ptr->media_addr);
- l_ptr->retransm_queue_head = mod(++r_q_head);
- l_ptr->retransm_queue_size = --r_q_size;
- l_ptr->stats.retransmitted++;
- return 0;
- }
+ struct sk_buff *buf = l_ptr->next_out;
/* Send one deferred data message, if send window not full: */
- buf = l_ptr->next_out;
if (buf) {
struct tipc_msg *msg = buf_msg(buf);
u32 next = msg_seqno(msg);
@@ -1025,8 +994,6 @@ void tipc_link_retransmit(struct tipc_link *l_ptr, struct sk_buff *buf,
retransmits--;
l_ptr->stats.retransmitted++;
}
-
- l_ptr->retransm_queue_head = l_ptr->retransm_queue_size = 0;
}
/**
diff --git a/net/tipc/link.h b/net/tipc/link.h
index fb3f99b..cc816aa 100644
--- a/net/tipc/link.h
+++ b/net/tipc/link.h
@@ -130,8 +130,6 @@ struct tipc_stats {
* @oldest_deferred_in: ptr to first inbound message in queue
* @newest_deferred_in: ptr to last inbound message in queue
* @unacked_window: # of inbound messages rx'd without ack'ing back to peer
- * @retransm_queue_size: number of messages to retransmit
- * @retransm_queue_head: sequence number of first message to retransmit
* @next_out: ptr to first unsent outbound message in queue
* @waiting_sks: linked list of sockets waiting for link congestion to abate
* @long_msg_seq_no: next identifier to use for outbound fragmented messages
@@ -190,8 +188,6 @@ struct tipc_link {
u32 unacked_window;
/* Congestion handling */
- u32 retransm_queue_size;
- u32 retransm_queue_head;
struct sk_buff *next_out;
struct sk_buff_head waiting_sks;
--
1.7.9.5
------------------------------------------------------------------------------
Download BIRT iHub F-Type - The Free Enterprise-Grade BIRT Server
from Actuate! Instantly Supercharge Your Business Reports and Dashboards
with Interactivity, Sharing, Native Excel Exports, App Integration & more
Get technology previously reserved for billion-dollar corporations, FREE
http://pubads.g.doubleclick.net/gampad/clk?id=157005751&iu=/4140/ostg.clktrk
^ permalink raw reply related
* [PATCH net-next 01/11] tipc: remove node subscription infrastructure
From: Ying Xue @ 2014-11-26 3:41 UTC (permalink / raw)
To: davem; +Cc: jon.maloy, netdev, Paul.Gortmaker, tipc-discussion
In-Reply-To: <1416973315-6047-1-git-send-email-ying.xue@windriver.com>
The node subscribe infrastructure represents a virtual base class, so
its users, such as struct tipc_port and struct publication, can derive
its implemented functionalities. However, after the removal of struct
tipc_port, struct publication is left as its only single user now. So
defining an abstract infrastructure for one user becomes no longer
reasonable. If corresponding new functions associated with the
infrastructure are moved to name_table.c file, the node subscription
infrastructure can be removed as well.
Signed-off-by: Ying Xue <ying.xue@windriver.com>
Reviewed-by: Jon Maloy <jon.maloy@ericsson.com>
---
net/tipc/Makefile | 4 +-
net/tipc/name_distr.c | 52 ++++++++++++++++++++++----
net/tipc/name_distr.h | 1 +
net/tipc/name_table.c | 2 +-
net/tipc/name_table.h | 6 +--
net/tipc/node.c | 6 +--
net/tipc/node.h | 5 +--
net/tipc/node_subscr.c | 96 ------------------------------------------------
net/tipc/node_subscr.h | 63 -------------------------------
9 files changed, 56 insertions(+), 179 deletions(-)
delete mode 100644 net/tipc/node_subscr.c
delete mode 100644 net/tipc/node_subscr.h
diff --git a/net/tipc/Makefile b/net/tipc/Makefile
index b8a13ca..333e459 100644
--- a/net/tipc/Makefile
+++ b/net/tipc/Makefile
@@ -7,8 +7,8 @@ obj-$(CONFIG_TIPC) := tipc.o
tipc-y += addr.o bcast.o bearer.o config.o \
core.o link.o discover.o msg.o \
name_distr.o subscr.o name_table.o net.o \
- netlink.o node.o node_subscr.o \
- socket.o log.o eth_media.o server.o
+ netlink.o node.o socket.o log.o eth_media.o \
+ server.o
tipc-$(CONFIG_TIPC_MEDIA_IB) += ib_media.o
tipc-$(CONFIG_SYSCTL) += sysctl.o
diff --git a/net/tipc/name_distr.c b/net/tipc/name_distr.c
index 376d2bb..6c2638d 100644
--- a/net/tipc/name_distr.c
+++ b/net/tipc/name_distr.c
@@ -250,13 +250,45 @@ void tipc_named_node_up(u32 dnode)
tipc_link_xmit(buf_chain, dnode, dnode);
}
+static void tipc_publ_subscribe(struct publication *publ, u32 addr)
+{
+ struct tipc_node *node;
+
+ if (in_own_node(addr))
+ return;
+
+ node = tipc_node_find(addr);
+ if (!node) {
+ pr_warn("Node subscription rejected, unknown node 0x%x\n",
+ addr);
+ return;
+ }
+
+ tipc_node_lock(node);
+ list_add_tail(&publ->nodesub_list, &node->publ_list);
+ tipc_node_unlock(node);
+}
+
+static void tipc_publ_unsubscribe(struct publication *publ, u32 addr)
+{
+ struct tipc_node *node;
+
+ node = tipc_node_find(addr);
+ if (!node)
+ return;
+
+ tipc_node_lock(node);
+ list_del_init(&publ->nodesub_list);
+ tipc_node_unlock(node);
+}
+
/**
- * named_purge_publ - remove publication associated with a failed node
+ * tipc_publ_purge - remove publication associated with a failed node
*
* Invoked for each publication issued by a newly failed node.
* Removes publication structure from name table & deletes it.
*/
-static void named_purge_publ(struct publication *publ)
+static void tipc_publ_purge(struct publication *publ, u32 addr)
{
struct publication *p;
@@ -264,7 +296,7 @@ static void named_purge_publ(struct publication *publ)
p = tipc_nametbl_remove_publ(publ->type, publ->lower,
publ->node, publ->ref, publ->key);
if (p)
- tipc_nodesub_unsubscribe(&p->subscr);
+ tipc_publ_unsubscribe(p, addr);
write_unlock_bh(&tipc_nametbl_lock);
if (p != publ) {
@@ -277,6 +309,14 @@ static void named_purge_publ(struct publication *publ)
kfree(p);
}
+void tipc_publ_notify(struct list_head *nsub_list, u32 addr)
+{
+ struct publication *publ, *tmp;
+
+ list_for_each_entry_safe(publ, tmp, nsub_list, nodesub_list)
+ tipc_publ_purge(publ, addr);
+}
+
/**
* tipc_update_nametbl - try to process a nametable update and notify
* subscribers
@@ -294,9 +334,7 @@ static bool tipc_update_nametbl(struct distr_item *i, u32 node, u32 dtype)
TIPC_CLUSTER_SCOPE, node,
ntohl(i->ref), ntohl(i->key));
if (publ) {
- tipc_nodesub_subscribe(&publ->subscr, node, publ,
- (net_ev_handler)
- named_purge_publ);
+ tipc_publ_subscribe(publ, node);
return true;
}
} else if (dtype == WITHDRAWAL) {
@@ -304,7 +342,7 @@ static bool tipc_update_nametbl(struct distr_item *i, u32 node, u32 dtype)
node, ntohl(i->ref),
ntohl(i->key));
if (publ) {
- tipc_nodesub_unsubscribe(&publ->subscr);
+ tipc_publ_unsubscribe(publ, node);
kfree(publ);
return true;
}
diff --git a/net/tipc/name_distr.h b/net/tipc/name_distr.h
index b9e75fe..cef55ce 100644
--- a/net/tipc/name_distr.h
+++ b/net/tipc/name_distr.h
@@ -74,5 +74,6 @@ void tipc_named_node_up(u32 dnode);
void tipc_named_rcv(struct sk_buff *buf);
void tipc_named_reinit(void);
void tipc_named_process_backlog(void);
+void tipc_publ_notify(struct list_head *nsub_list, u32 addr);
#endif
diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c
index 7cfb7a4..772be1c 100644
--- a/net/tipc/name_table.c
+++ b/net/tipc/name_table.c
@@ -144,7 +144,7 @@ static struct publication *publ_create(u32 type, u32 lower, u32 upper,
publ->key = key;
INIT_LIST_HEAD(&publ->local_list);
INIT_LIST_HEAD(&publ->pport_list);
- INIT_LIST_HEAD(&publ->subscr.nodesub_list);
+ INIT_LIST_HEAD(&publ->nodesub_list);
return publ;
}
diff --git a/net/tipc/name_table.h b/net/tipc/name_table.h
index b38ebec..c628778 100644
--- a/net/tipc/name_table.h
+++ b/net/tipc/name_table.h
@@ -37,8 +37,6 @@
#ifndef _TIPC_NAME_TABLE_H
#define _TIPC_NAME_TABLE_H
-#include "node_subscr.h"
-
struct tipc_subscription;
struct tipc_port_list;
@@ -56,7 +54,7 @@ struct tipc_port_list;
* @node: network address of publishing port's node
* @ref: publishing port
* @key: publication key
- * @subscr: subscription to "node down" event (for off-node publications only)
+ * @nodesub_list: subscription to "node down" event (off-node publication only)
* @local_list: adjacent entries in list of publications made by this node
* @pport_list: adjacent entries in list of publications made by this port
* @node_list: adjacent matching name seq publications with >= node scope
@@ -73,7 +71,7 @@ struct publication {
u32 node;
u32 ref;
u32 key;
- struct tipc_node_subscr subscr;
+ struct list_head nodesub_list;
struct list_head local_list;
struct list_head pport_list;
struct list_head node_list;
diff --git a/net/tipc/node.c b/net/tipc/node.c
index 82e5edd..17b8092 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -113,7 +113,7 @@ struct tipc_node *tipc_node_create(u32 addr)
spin_lock_init(&n_ptr->lock);
INIT_HLIST_NODE(&n_ptr->hash);
INIT_LIST_HEAD(&n_ptr->list);
- INIT_LIST_HEAD(&n_ptr->nsub);
+ INIT_LIST_HEAD(&n_ptr->publ_list);
INIT_LIST_HEAD(&n_ptr->conn_sks);
__skb_queue_head_init(&n_ptr->waiting_sks);
@@ -574,7 +574,7 @@ void tipc_node_unlock(struct tipc_node *node)
skb_queue_splice_init(&node->waiting_sks, &waiting_sks);
if (flags & TIPC_NOTIFY_NODE_DOWN) {
- list_replace_init(&node->nsub, &nsub_list);
+ list_replace_init(&node->publ_list, &nsub_list);
list_replace_init(&node->conn_sks, &conn_sks);
}
node->action_flags &= ~(TIPC_WAKEUP_USERS | TIPC_NOTIFY_NODE_DOWN |
@@ -591,7 +591,7 @@ void tipc_node_unlock(struct tipc_node *node)
tipc_node_abort_sock_conns(&conn_sks);
if (!list_empty(&nsub_list))
- tipc_nodesub_notify(&nsub_list);
+ tipc_publ_notify(&nsub_list, addr);
if (flags & TIPC_WAKEUP_BCAST_USERS)
tipc_bclink_wakeup_users();
diff --git a/net/tipc/node.h b/net/tipc/node.h
index 005fbce..f199451 100644
--- a/net/tipc/node.h
+++ b/net/tipc/node.h
@@ -37,7 +37,6 @@
#ifndef _TIPC_NODE_H
#define _TIPC_NODE_H
-#include "node_subscr.h"
#include "addr.h"
#include "net.h"
#include "bearer.h"
@@ -104,7 +103,7 @@ struct tipc_node_bclink {
* @link_cnt: number of links to node
* @signature: node instance identifier
* @link_id: local and remote bearer ids of changing link, if any
- * @nsub: list of "node down" subscriptions monitoring node
+ * @publ_list: list of publications
* @rcu: rcu struct for tipc_node
*/
struct tipc_node {
@@ -121,7 +120,7 @@ struct tipc_node {
int working_links;
u32 signature;
u32 link_id;
- struct list_head nsub;
+ struct list_head publ_list;
struct sk_buff_head waiting_sks;
struct list_head conn_sks;
struct rcu_head rcu;
diff --git a/net/tipc/node_subscr.c b/net/tipc/node_subscr.c
deleted file mode 100644
index 2d13eea..0000000
--- a/net/tipc/node_subscr.c
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * net/tipc/node_subscr.c: TIPC "node down" subscription handling
- *
- * Copyright (c) 1995-2006, Ericsson AB
- * Copyright (c) 2005, 2010-2011, Wind River Systems
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the names of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * Alternatively, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") version 2 as published by the Free
- * Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "core.h"
-#include "node_subscr.h"
-#include "node.h"
-
-/**
- * tipc_nodesub_subscribe - create "node down" subscription for specified node
- */
-void tipc_nodesub_subscribe(struct tipc_node_subscr *node_sub, u32 addr,
- void *usr_handle, net_ev_handler handle_down)
-{
- if (in_own_node(addr)) {
- node_sub->node = NULL;
- return;
- }
-
- node_sub->node = tipc_node_find(addr);
- if (!node_sub->node) {
- pr_warn("Node subscription rejected, unknown node 0x%x\n",
- addr);
- return;
- }
- node_sub->handle_node_down = handle_down;
- node_sub->usr_handle = usr_handle;
-
- tipc_node_lock(node_sub->node);
- list_add_tail(&node_sub->nodesub_list, &node_sub->node->nsub);
- tipc_node_unlock(node_sub->node);
-}
-
-/**
- * tipc_nodesub_unsubscribe - cancel "node down" subscription (if any)
- */
-void tipc_nodesub_unsubscribe(struct tipc_node_subscr *node_sub)
-{
- if (!node_sub->node)
- return;
-
- tipc_node_lock(node_sub->node);
- list_del_init(&node_sub->nodesub_list);
- tipc_node_unlock(node_sub->node);
-}
-
-/**
- * tipc_nodesub_notify - notify subscribers that a node is unreachable
- *
- * Note: node is locked by caller
- */
-void tipc_nodesub_notify(struct list_head *nsub_list)
-{
- struct tipc_node_subscr *ns, *safe;
- net_ev_handler handle_node_down;
-
- list_for_each_entry_safe(ns, safe, nsub_list, nodesub_list) {
- handle_node_down = ns->handle_node_down;
- if (handle_node_down) {
- ns->handle_node_down = NULL;
- handle_node_down(ns->usr_handle);
- }
- }
-}
diff --git a/net/tipc/node_subscr.h b/net/tipc/node_subscr.h
deleted file mode 100644
index d91b8cc..0000000
--- a/net/tipc/node_subscr.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * net/tipc/node_subscr.h: Include file for TIPC "node down" subscription handling
- *
- * Copyright (c) 1995-2006, Ericsson AB
- * Copyright (c) 2005, 2010-2011, Wind River Systems
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the names of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * Alternatively, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") version 2 as published by the Free
- * Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _TIPC_NODE_SUBSCR_H
-#define _TIPC_NODE_SUBSCR_H
-
-#include "addr.h"
-
-typedef void (*net_ev_handler) (void *usr_handle);
-
-/**
- * struct tipc_node_subscr - "node down" subscription entry
- * @node: ptr to node structure of interest (or NULL, if none)
- * @handle_node_down: routine to invoke when node fails
- * @usr_handle: argument to pass to routine when node fails
- * @nodesub_list: adjacent entries in list of subscriptions for the node
- */
-struct tipc_node_subscr {
- struct tipc_node *node;
- net_ev_handler handle_node_down;
- void *usr_handle;
- struct list_head nodesub_list;
-};
-
-void tipc_nodesub_subscribe(struct tipc_node_subscr *node_sub, u32 addr,
- void *usr_handle, net_ev_handler handle_down);
-void tipc_nodesub_unsubscribe(struct tipc_node_subscr *node_sub);
-void tipc_nodesub_notify(struct list_head *nsub_list);
-
-#endif
--
1.7.9.5
------------------------------------------------------------------------------
Download BIRT iHub F-Type - The Free Enterprise-Grade BIRT Server
from Actuate! Instantly Supercharge Your Business Reports and Dashboards
with Interactivity, Sharing, Native Excel Exports, App Integration & more
Get technology previously reserved for billion-dollar corporations, FREE
http://pubads.g.doubleclick.net/gampad/clk?id=157005751&iu=/4140/ostg.clktrk
^ permalink raw reply related
* Re: [PATCH net 0/2] net: dsa: bcm_sf2: misc bugfixes
From: David Miller @ 2014-11-26 3:39 UTC (permalink / raw)
To: f.fainelli; +Cc: netdev
In-Reply-To: <1416967711-32494-1-git-send-email-f.fainelli@gmail.com>
From: Florian Fainelli <f.fainelli@gmail.com>
Date: Tue, 25 Nov 2014 18:08:29 -0800
> This patch series contains two bug fixes:
>
> - first patch fixes an issue on the error path of the driver where we could
> have left some of our registers mapped
>
> - second patch enforces the use of a software reset of the switch to guarantee
> the HW is in a consistent state prior to software initialization
Series applied, thanks Florian.
^ permalink raw reply
* Re: [patch net-next v3 04/17] net: introduce generic switch devices support
From: Jamal Hadi Salim @ 2014-11-26 3:33 UTC (permalink / raw)
To: Thomas Graf
Cc: Jiri Pirko, netdev, davem, nhorman, andy, dborkman, ogerlitz,
jesse, pshelar, azhou, ben, stephen, jeffrey.t.kirsher, vyasevic,
xiyou.wangcong, john.r.fastabend, edumazet, sfeldma, f.fainelli,
roopa, linville, jasowang, ebiederm, nicolas.dichtel,
ryazanov.s.a, buytenh, aviadr, nbd, alexei.starovoitov,
Neil.Jerram, ronye, simon.horman, alexander.h.duyck, john.ronciak,
mleitner, shrijeet, gospo, bcrl
In-Reply-To: <20141125215402.GA3912@casper.infradead.org>
On 11/25/14 16:54, Thomas Graf wrote:
> On 11/25/14 at 12:08pm, Jamal Hadi Salim wrote:
> It would definitely help if you could expose some more details on the
> "some network processor" you have. We're all very eager ;-)
>
Well, this thing doesnt run ovs ;-> (/me runs). If you come
to netdev i may let you play with it ;-> Its a humongous device
(think multi 100G ports).
On a serious note: Even if you took what Simon/Netronome has
(yes, I know they use ovs;->) - there is really no need for a switch
abstraction *at all* if all you want to is hang a packet
processing graph that ingresses at a port and egress at another port.
As you know, Linux supports it just fine with tc.
> I'm with Jiri but I agree it's not a perfect fit. I doubt there is but
> if you can come up with something that fits better I'm open to it.
>
> I considered "dataplane" or "dp" for a bit but it's quite generic as
> well.
>
The purpose is to offload. I think any name would be better than
mapping it to a specific abstraction called "switch". Especially
if it is hanging off a port and there is no switch in the pipeline.
cheers,
jamal
^ permalink raw reply
* Re: [patch net-next v3 09/17] bridge: add API to notify bridge driver of learned FBD on offloaded device
From: Jamal Hadi Salim @ 2014-11-26 3:22 UTC (permalink / raw)
To: Florian Fainelli, Jiri Pirko, netdev
Cc: davem, nhorman, andy, tgraf, dborkman, ogerlitz, jesse, pshelar,
azhou, ben, stephen, jeffrey.t.kirsher, vyasevic, xiyou.wangcong,
john.r.fastabend, edumazet, sfeldma, roopa, linville, jasowang,
ebiederm, nicolas.dichtel, ryazanov.s.a, buytenh, aviadr, nbd,
alexei.starovoitov, Neil.Jerram, ronye, simon.horman,
alexander.h.duyck, john.ronciak, mleitner, shrijeet, gospo, bcrl
In-Reply-To: <54750669.4090406@gmail.com>
On 11/25/14 17:44, Florian Fainelli wrote:
> On 25/11/14 02:28, Jiri Pirko wrote:
>> @@ -101,6 +101,7 @@ struct net_bridge_fdb_entry
>> unsigned char is_local;
>> unsigned char is_static;
>> unsigned char added_by_user;
>> + unsigned char added_by_external_learn;
>
> Pheww, we could be saving some memory footprint here by using different
> types here ;)
I tried to bring up this issue earlier.
Unfortuately about 15 different things being transfered over bridge
netlink use 8 bits for representing a bit of information.
A bitmap selector would be a lot more efficient. Not unusual to have a
few hundred thousand entries.
cheers,
jamal
> --
> Florian
>
^ permalink raw reply
* Re: [patch net-next v3 02/17] net: make vid as a parameter for ndo_fdb_add/ndo_fdb_del
From: Jamal Hadi Salim @ 2014-11-26 3:19 UTC (permalink / raw)
To: Scott Feldman
Cc: John Fastabend, Jiri Pirko, Netdev, David S. Miller,
nhorman@tuxdriver.com, Andy Gospodarek, Thomas Graf,
dborkman@redhat.com, ogerlitz@mellanox.com, jesse@nicira.com,
pshelar@nicira.com, azhou@nicira.com, ben@decadent.org.uk,
stephen@networkplumber.org, Kirsher, Jeffrey T,
vyasevic@redhat.com, Cong Wang, Eric Dumazet, Florian Fainelli,
Roopa Prabhu, John Linville
In-Reply-To: <CAE4R7bD1Hi+fnKp-Sg6Tn4AcpOu2pwgEYecP8LVA1ioO4FkgRQ@mail.gmail.com>
On 11/25/14 21:36, Scott Feldman wrote:
> On Tue, Nov 25, 2014 at 6:50 AM, Jamal Hadi Salim <jhs@mojatatu.com> wrote:
>> On 11/25/14 11:30, John Fastabend wrote:
>> Ok, guess i am gonna have to go stare at the code some more.
>> I thought we returned one of the error codes?
>> A bitmask would work for a single entry - because you have two
>> options add to h/ware and/or s/ware. So response is easy to encode.
>> But if i have 1000 and they are sparsely populated (think an indexed
>> table and i have indices 1, 23, 45, etc), then a bitmask would be
>> hard to use.
>
> I'm confused by this discussion.
This is about the policy which states "install as many as you can, dont
worry about failures". In such a case, how do you tell user space back
"oh, btw you know your request #1, #23, and 45 went ok, but nothing else
worked". A simple return code wont work. You could return a code to
say "some worked". At which case user space could dump and find out only
#1, #23 and #45 worked.
Your question below is a different context; Some people may want
the policy where whats in hardware
a) gets to be seen in software and b) allow for destination lookup
failures in hardware to show up in the kernel, refresh the fdb in the
kernel via learning
and c) whats in s.ware gets synced to hardware just because there's
space in the hardware
I dont want any of the above;-> Which would work if we had policy knobs.
Learning, flooding, sync from hardware. Speaking of the last one:
Where is my cookie Scott? I want my cookie.
cheers,
jamal
> Do I have this right: You want to
> send 1000 RTM_NEWNEIGHs to PF_BRIDGE with both NTF_MASTER and NTF_SELF
> set such that 1000 new FBD entries are installed in both (SW) the
> bridge's FDB and (HW) the port driver's FDB. My first confusion is
> why do you want these FBD entries in bridge's FDB? We're offloading
> the switching to HW so HW should be handling fwd plane. If ctrl pkt
> make it to SW, it can learn those FDB entries;
> no need for manual
> install of FDB entry in SW. It seems to me you only want to use
> NTF_SELF to install the FDB entry in HW using the port driver. And an
> error code is returned for that install. Since there is only one
> target (NTF_SELF) there is no need for bitmask return.
^ permalink raw reply
* Re: [net-next PATCH 2/5] ethernet/intel: Use eth_skb_pad helper
From: David Miller @ 2014-11-26 3:19 UTC (permalink / raw)
To: eric.dumazet
Cc: alexander.duyck, alexander.h.duyck, netdev, jeffrey.t.kirsher
In-Reply-To: <1416966185.29427.46.camel@edumazet-glaptop2.roam.corp.google.com>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Tue, 25 Nov 2014 17:43:05 -0800
> I believe I finally have an idea why we had various + 15 in skb
> allocations in TCP stack !
It was so that you could do one level of tunneling with "for
free". Or that is my recollection.
Those + 15 existed way before any of these padto() calls even
existed.
^ permalink raw reply
* Re: [PATCH 3/4] GMAC: dts: add gmac info for rk3288
From: Roger @ 2014-11-26 2:49 UTC (permalink / raw)
To: Heiko Stübner
Cc: Sergei Shtylyov, peppe.cavallaro, netdev, linux-kernel,
linux-rockchip, kever.yang, mark.yao, eddie.cai
In-Reply-To: <1773507.kOcjDCLbcs@diego>
On 2014/11/25 22:39, Heiko Stübner wrote:
> Am Dienstag, 25. November 2014, 16:40:59 schrieb Sergei Shtylyov:
>> Hello.
>>
>> On 11/25/2014 12:08 PM, Roger Chen wrote:
>>> add gmac info in rk3288.dtsi for GMAC driver
>>>
>>> Signed-off-by: Roger Chen <roger.chen@rock-chips.com>
>>> ---
>>>
>>> arch/arm/boot/dts/rk3288.dtsi | 59
>>> +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59
>>> insertions(+)
>>>
>>> diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi
>>> index 0f50d5d..949675d 100644
>>> --- a/arch/arm/boot/dts/rk3288.dtsi
>>> +++ b/arch/arm/boot/dts/rk3288.dtsi
>> [...]
>>
>>> @@ -490,6 +497,25 @@
>>>
>>> reg = <0xff740000 0x1000>;
>>>
>>> };
>>>
>>> + gmac: eth@ff290000 {
>> Please name the node "ethernet@ff290000" to comply with the ePAPR
>> standard.
>>> + compatible = "rockchip,rk3288-gmac";
>>> + reg = <0xff290000 0x10000>;
>>> + interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>; /*irq=59*/
>>> + interrupt-names = "macirq";
>>> + rockchip,grf = <&grf>;
>>> + clocks = <&cru SCLK_MAC>, <&cru SCLK_MAC_PLL>,
>>> + <&cru SCLK_MAC_RX>, <&cru SCLK_MAC_TX>,
>>> + <&cru SCLK_MACREF>, <&cru SCLK_MACREF_OUT>,
>>> + <&cru ACLK_GMAC>, <&cru PCLK_GMAC>;
>>> + clock-names = "stmmaceth", "clk_mac_pll",
>>> + "mac_clk_rx", "mac_clk_tx",
>>> + "clk_mac_ref", "clk_mac_refout",
>>> + "aclk_mac", "pclk_mac";
>>> + phy-mode = "rgmii";
>>> + pinctrl-names = "default";
>>> + pinctrl-0 = <&rgmii_pin /*&rmii_pin*/>;
>> Hm, pinctrl props in a .dtsi file? Those are usually board dependent.
> yep, especially as there is a board-dependent selection needed of what to use
> [rgmii or rmii] depending on the phy on the board.
of course pinctrl props is redefined in the rk3288-evb-rk808.dts,
IMO, pinctrl props in .dtsi is used to fit for the "phy-mode" prop as default.
if pinctrl props should be removed, how about "phy-mode" prop?
>> [...]
>>
>>> @@ -1040,5 +1066,38 @@
>>>
>>> rockchip,pins = <7 23 3 &pcfg_pull_none>;
>>>
>>> };
>>>
>>> };
>>>
>>> +
>>> + gmac {
>>> + rgmii_pin: rgmii-pins {
> please add the "s" to the label - "rgmii_pins"
>
>
>>> + rockchip,pins = <3 30 3 &pcfg_pull_none>,
>>> + <3 31 3 &pcfg_pull_none>,
>>> + <3 26 3 &pcfg_pull_none>,
>>> + <3 27 3 &pcfg_pull_none>,
>>> + <3 28 3 &pcfg_pull_none>,
>>> + <3 29 3 &pcfg_pull_none>,
>>> + <3 24 3 &pcfg_pull_none>,
>>> + <3 25 3 &pcfg_pull_none>,
>>> + <4 0 3 &pcfg_pull_none>,
>>> + <4 5 3 &pcfg_pull_none>,
>>> + <4 6 3 &pcfg_pull_none>,
>>> + <4 9 3 &pcfg_pull_none>,
>>> + <4 4 3 &pcfg_pull_none>,
>>> + <4 1 3 &pcfg_pull_none>,
>>> + <4 3 3 &pcfg_pull_none>;
>>> + };
>>> +
>>> + rmii_pin: rmii-pins {
> same here
>
>
>>> + rockchip,pins = <3 30 3 &pcfg_pull_none>,
>>> + <3 31 3 &pcfg_pull_none>,
>>> + <3 28 3 &pcfg_pull_none>,
>>> + <3 29 3 &pcfg_pull_none>,
>>> + <4 0 3 &pcfg_pull_none>,
>>> + <4 5 3 &pcfg_pull_none>,
>>> + <4 4 3 &pcfg_pull_none>,
>>> + <4 1 3 &pcfg_pull_none>,
>>> + <4 2 3 &pcfg_pull_none>,
>>> + <4 3 3 &pcfg_pull_none>;
>>> + };
>>> + };
>> These are usually define in the board .dts file...
> The pinctrl settings itself are soc-specific, i.e. the pins and their settings
> to use to enable r{g}mii functionality are the same for all boards using this
> soc, so the pinctrl definitions should stay here and not be redefined in each
> and every board file.
>
>
> Heiko
>
>
>
^ permalink raw reply
* Re: [net-next PATCH 1/5] etherdevice: Add function for handling padding frame to ETH_ZLEN
From: Alexander Duyck @ 2014-11-26 2:44 UTC (permalink / raw)
To: Florian Fainelli, Alexander Duyck, netdev; +Cc: davem
In-Reply-To: <54752525.4040509@gmail.com>
On 11/25/2014 04:56 PM, Florian Fainelli wrote:
> On 25/11/14 14:44, Alexander Duyck wrote:
>> This patch adds a simple function for padding a frame up to the minimum
>> size for for Ethernet. The motivation behind it is that there are a number
>> of implementations throughout the network device drivers that are all doing
>> the same thing, but each a little bit differently and as a result several
>> implementations contain bugs such as updating the length without updating
>> the tail offset and other similar issues.
>>
>> Signed-off-by: Alexander Duyck <alexander.h.duyck@redhat.com>
>> ---
>> include/linux/etherdevice.h | 21 +++++++++++++++++++++
>> 1 file changed, 21 insertions(+)
>>
>> diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h
>> index 733980f..7e436f3 100644
>> --- a/include/linux/etherdevice.h
>> +++ b/include/linux/etherdevice.h
>> @@ -392,4 +392,25 @@ static inline unsigned long compare_ether_header(const void *a, const void *b)
>> #endif
>> }
>>
>> +/**
>> + * eth_skb_pad - Pad buffer to mininum number of octets for Ethernet frame
>> + * @skb: Buffer to pad
>> + *
>> + * An Ethernet frame should have a minimum size of 60 bytes. This function
>> + * takes short frames and pads them with zeros up to the 60 byte limit.
>
> minimum size without FCS
>
>> + */
>> +static inline int eth_skb_pad(struct sk_buff *skb)
>> +{
>> + unsigned int size = skb->len;
>> +
>> + if (unlikely(size < ETH_ZLEN)) {
>> + size = ETH_ZLEN - size;
>> + if (skb_pad(skb, size))
>> + return -ENOMEM;
>> + __skb_put(skb, size);
>> + }
>
> most drivers call skb_padto(skb, ETH_ZLEN), besides the extra
> __skb_put() here, this is not different.
Yes, but the __skb_put is the difference. Calling skb_padto() only
zeros out the bytes following the tail, but it doesn't add the extra
bytes to the frame nor does it update the tail. As such if we only call
skb_padto() before handing a short frame off to the network stack the
network stack will still have issues with it being too short.
The difference between the two is that skb_padto() is really meant for
transmit, whereas eth_skb_pad is really meant for receive.
- Alex
^ permalink raw reply
* Re: [patch net-next v3 09/17] bridge: add API to notify bridge driver of learned FBD on offloaded device
From: Scott Feldman @ 2014-11-26 2:40 UTC (permalink / raw)
To: Florian Fainelli
Cc: Jiri Pirko, Netdev, David S. Miller, nhorman@tuxdriver.com,
Andy Gospodarek, Thomas Graf, dborkman@redhat.com,
ogerlitz@mellanox.com, jesse@nicira.com, pshelar@nicira.com,
azhou@nicira.com, ben@decadent.org.uk, stephen@networkplumber.org,
Kirsher, Jeffrey T, vyasevic@redhat.com, Cong Wang,
Fastabend, John R, Eric Dumazet, Jamal Hadi Salim, Roopa Prabhu,
John Linville
In-Reply-To: <54753C1F.1080109@gmail.com>
On Tue, Nov 25, 2014 at 4:34 PM, Florian Fainelli <f.fainelli@gmail.com> wrote:
> On 25/11/14 18:03, Scott Feldman wrote:
>> On Tue, Nov 25, 2014 at 12:44 PM, Florian Fainelli <f.fainelli@gmail.com> wrote:
>>> On 25/11/14 02:28, Jiri Pirko wrote:
>>>> From: Scott Feldman <sfeldma@gmail.com>
>>>>
>>>> When the swdev device learns a new mac/vlan on a port, it sends some async
>>>> notification to the driver and the driver installs an FDB in the device.
>>>> To give a holistic system view, the learned mac/vlan should be reflected
>>>> in the bridge's FBD table, so the user, using normal iproute2 cmds, can view
>>>> what is currently learned by the device. This API on the bridge driver gives
>>>> a way for the swdev driver to install an FBD entry in the bridge FBD table.
>>>> (And remove one).
>>>>
>>>> This is equivalent to the device running these cmds:
>>>>
>>>> bridge fdb [add|del] <mac> dev <dev> vid <vlan id> master
>>>>
>>>> This patch needs some extra eyeballs for review, in paricular around the
>>>> locking and contexts.
>>>>
>>>> Signed-off-by: Scott Feldman <sfeldma@gmail.com>
>>>> Signed-off-by: Jiri Pirko <jiri@resnulli.us>
>>>> ---
>>>
>>> [snip]
>>>
>>>> + head = &br->hash[br_mac_hash(addr, vid)];
>>>> + fdb = fdb_find(head, addr, vid);
>>>> + if (!fdb) {
>>>> + fdb = fdb_create(head, p, addr, vid);
>>>> + if (!fdb) {
>>>> + err = -ENOMEM;
>>>> + goto err_unlock;
>>>> + }
>>>> + fdb->added_by_external_learn = 1;
>>>> + fdb_notify(br, fdb, RTM_NEWNEIGH);
>>>> + } else if (fdb->added_by_external_learn) {
>>>> + /* Refresh entry */
>>>> + fdb->updated = fdb->used = jiffies;
>>>> + } else if (!fdb->added_by_user) {
>>>> + /* Take over SW learned entry */
>>>> + fdb->added_by_external_learn = 1;
>>>> + fdb->updated = jiffies;
>>>> + fdb_notify(br, fdb, RTM_NEWNEIGH);
>>>> + }
>>>
>>> Is there any case where this fdb entry gets re-used and is no longer
>>> added by an external learning? Should we clear this flag somewhere?
>>
>> Once the FDB entry is marked "added_by_external_learn" it stays marked
>> as such until removed by aging cleanup process (or flushed due to
>> interface down, etc). If aged out (and now deleted), the FDB entry
>> may come back either by SW learn or by HW learn. If SW learn comes
>> first, and then HW learn, HW learn will override and mark the existing
>> FDB entry "added_by_external_learn". So there is take-over by HW but
>> no give-back to SW. And there is no explicit clearing of the mark
>> short of deleting the FDB entry. The mark is mostly for letting
>> user's know which FDB entries where learned by HW and synced to the
>> bridge's FDB.
>
> Thanks, makes sense now. This is probably obvious in this context, but
> maybe it would not hurt to come up with a documentation that describe
> the offload API, FDB entry lifetime and HW/SW ownership etc...
I have an updated Documentation/networking/switchdev.txt that covers
the swdev APIs and usage and notes, but Jiri is being stingy with it.
Will get this out, either in v4 or follow-on patches. There is enough
going on just with L2 offload that we're going to need some good
documentation to guide implementers.
^ permalink raw reply
* [PATCH] stmmac: platform: fix default values of the filter bins setting
From: Huacai Chen @ 2014-11-26 2:38 UTC (permalink / raw)
To: Giuseppe Cavallaro; +Cc: Vince Bridgers, David S. Miller, netdev, Huacai Chen
The commit 3b57de958e2a brought the support for a different amount of
the filter bins, but didn't update the platform driver that without
CONFIG_OF.
Fixes: 3b57de958e2a (net: stmmac: Support devicetree configs for mcast
and ucast filter entries)
Signed-off-by: Huacai Chen <chenhc@lemote.com>
---
.../net/ethernet/stmicro/stmmac/stmmac_platform.c | 13 +++++++------
1 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
index db56fa7..5b0da39 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
@@ -177,12 +177,6 @@ static int stmmac_probe_config_dt(struct platform_device *pdev,
*/
plat->maxmtu = JUMBO_LEN;
- /* Set default value for multicast hash bins */
- plat->multicast_filter_bins = HASH_TABLE_SIZE;
-
- /* Set default value for unicast filter entries */
- plat->unicast_filter_entries = 1;
-
/*
* Currently only the properties needed on SPEAr600
* are provided. All other properties should be added
@@ -270,6 +264,13 @@ static int stmmac_pltfr_probe(struct platform_device *pdev)
return PTR_ERR(addr);
plat_dat = dev_get_platdata(&pdev->dev);
+
+ /* Set default value for multicast hash bins */
+ plat_dat->multicast_filter_bins = HASH_TABLE_SIZE;
+
+ /* Set default value for unicast filter entries */
+ plat_dat->unicast_filter_entries = 1;
+
if (pdev->dev.of_node) {
if (!plat_dat)
plat_dat = devm_kzalloc(&pdev->dev,
--
1.7.7.3
^ permalink raw reply related
* Re: [patch net-next v3 02/17] net: make vid as a parameter for ndo_fdb_add/ndo_fdb_del
From: Scott Feldman @ 2014-11-26 2:36 UTC (permalink / raw)
To: Jamal Hadi Salim
Cc: John Fastabend, Jiri Pirko, Netdev, David S. Miller,
nhorman@tuxdriver.com, Andy Gospodarek, Thomas Graf,
dborkman@redhat.com, ogerlitz@mellanox.com, jesse@nicira.com,
pshelar@nicira.com, azhou@nicira.com, ben@decadent.org.uk,
stephen@networkplumber.org, Kirsher, Jeffrey T,
vyasevic@redhat.com, Cong Wang, Eric Dumazet, Florian Fainelli,
Roopa Prabhu, John Linville
In-Reply-To: <5474B353.10802@mojatatu.com>
On Tue, Nov 25, 2014 at 6:50 AM, Jamal Hadi Salim <jhs@mojatatu.com> wrote:
> On 11/25/14 11:30, John Fastabend wrote:
>>
>> On 11/25/2014 08:18 AM, Jamal Hadi Salim wrote:
>>>
>>> On 11/25/14 11:01, John Fastabend wrote:
>>>>
>>>> On 11/25/2014 07:38 AM, Jamal Hadi Salim wrote:
>>>>>
>>>>> On 11/25/14 05:28, Jiri Pirko wrote:
>>>>>>
>>>>>> Do the work of parsing NDA_VLAN directly in rtnetlink code, pass
>>>>>> simple
>>>>>> u16 vid to drivers from there.
>>>>>>
>>>>>
>
>
>> Actually (after having some coffee) this becomes much more useful
>> if you return which items failed. Then you can slam the hardware
>> with your 100 entries, probably a lot more then that, and come back
>> later and clean it up.
>>
>
> Yes, that is the general use case.
> Unfortunately at the moment we only return codes on a netlink set
> direction - but would be a beauty if we could return what succeeded
> and didnt in some form of vector.
> Note: all is not lost because you can always do a get afterwards and
> find what is missing if you got a return code of "partial success".
> Just a little less efficient..
>
>
>> We return a bitmask of which operations were successful. So if SW fails
>> we have both bits cleared and we abort. When SW is successful we set the
>> SW bit and try to program the HW. If its sucessful we set the HW bit if
>> its not we abort with an err. Converting this to (1) is not much work
>> just skip the abort.
>>
>
> Ok, guess i am gonna have to go stare at the code some more.
> I thought we returned one of the error codes?
> A bitmask would work for a single entry - because you have two
> options add to h/ware and/or s/ware. So response is easy to encode.
> But if i have 1000 and they are sparsely populated (think an indexed
> table and i have indices 1, 23, 45, etc), then a bitmask would be
> hard to use.
I'm confused by this discussion. Do I have this right: You want to
send 1000 RTM_NEWNEIGHs to PF_BRIDGE with both NTF_MASTER and NTF_SELF
set such that 1000 new FBD entries are installed in both (SW) the
bridge's FDB and (HW) the port driver's FDB. My first confusion is
why do you want these FBD entries in bridge's FDB? We're offloading
the switching to HW so HW should be handling fwd plane. If ctrl pkt
make it to SW, it can learn those FDB entries; no need for manual
install of FDB entry in SW. It seems to me you only want to use
NTF_SELF to install the FDB entry in HW using the port driver. And an
error code is returned for that install. Since there is only one
target (NTF_SELF) there is no need for bitmask return.
> cheers,
> jamal
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox