Merge "net: rmnet_data: adding support to GRO"

This commit is contained in:
Linux Build Service Account 2015-06-09 13:04:55 -07:00 committed by Gerrit - the friendly Code Review server
commit ea0e4d4ab4
5 changed files with 79 additions and 4 deletions

View File

@ -1795,6 +1795,7 @@ struct softnet_data {
struct Qdisc *output_queue;
struct Qdisc **output_queue_tailp;
struct list_head poll_list;
struct napi_struct *current_napi;
struct sk_buff *completion_queue;
struct sk_buff_head process_queue;
@ -2216,6 +2217,7 @@ extern gro_result_t napi_gro_receive(struct napi_struct *napi,
extern void napi_gro_flush(struct napi_struct *napi, bool flush_old);
extern struct sk_buff * napi_get_frags(struct napi_struct *napi);
extern gro_result_t napi_gro_frags(struct napi_struct *napi);
extern struct napi_struct *get_current_napi_context(void);
static inline void napi_free_frags(struct napi_struct *napi)
{

View File

@ -4021,6 +4021,7 @@ static int process_backlog(struct napi_struct *napi, int quota)
{
int work = 0;
struct softnet_data *sd = container_of(napi, struct softnet_data, backlog);
static int quota_changed;
#ifdef CONFIG_RPS
/* Check if we have pending ipi, its better to send them now,
@ -4043,7 +4044,14 @@ static int process_backlog(struct napi_struct *napi, int quota)
local_irq_disable();
input_queue_head_incr(sd);
if (++work >= quota) {
if (quota_changed) {
local_irq_enable();
napi_gro_flush(napi, false);
local_irq_disable();
quota_changed = 0;
}
local_irq_enable();
sd->current_napi = NULL;
return work;
}
}
@ -4066,10 +4074,12 @@ static int process_backlog(struct napi_struct *napi, int quota)
napi->state = 0;
quota = work + qlen;
quota_changed = 1;
}
rps_unlock(sd);
}
local_irq_enable();
sd->current_napi = NULL;
return work;
}
@ -4092,11 +4102,14 @@ EXPORT_SYMBOL(__napi_schedule);
void __napi_complete(struct napi_struct *n)
{
struct softnet_data *sd = &__get_cpu_var(softnet_data);
BUG_ON(!test_bit(NAPI_STATE_SCHED, &n->state));
BUG_ON(n->gro_list);
list_del(&n->poll_list);
smp_mb__before_atomic();
sd->current_napi = NULL;
clear_bit(NAPI_STATE_SCHED, &n->state);
}
EXPORT_SYMBOL(__napi_complete);
@ -4159,6 +4172,13 @@ void netif_napi_del(struct napi_struct *napi)
}
EXPORT_SYMBOL(netif_napi_del);
struct napi_struct *get_current_napi_context(void)
{
struct softnet_data *sd = &__get_cpu_var(softnet_data);
return sd->current_napi;
}
EXPORT_SYMBOL(get_current_napi_context);
static void net_rx_action(struct softirq_action *h)
{
struct softnet_data *sd = &__get_cpu_var(softnet_data);
@ -4200,6 +4220,7 @@ static void net_rx_action(struct softirq_action *h)
*/
work = 0;
if (test_bit(NAPI_STATE_SCHED, &n->state)) {
sd->current_napi = n;
work = n->poll(n, weight);
trace_napi_poll(n);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@ -163,6 +163,20 @@ static rx_handler_result_t rmnet_bridge_handler(struct sk_buff *skb,
return RX_HANDLER_CONSUMED;
}
#ifdef NET_SKBUFF_DATA_USES_OFFSET
static void rmnet_reset_mac_header(struct sk_buff *skb)
{
skb->mac_header = 0;
skb->mac_len = 0;
}
#else
static void rmnet_reset_mac_header(struct sk_buff *skb)
{
skb->mac_header = skb->data;
skb->mac_len = 0;
}
#endif /*NET_SKBUFF_DATA_USES_OFFSET*/
/**
* __rmnet_deliver_skb() - Deliver skb
*
@ -176,6 +190,9 @@ static rx_handler_result_t rmnet_bridge_handler(struct sk_buff *skb,
static rx_handler_result_t __rmnet_deliver_skb(struct sk_buff *skb,
struct rmnet_logical_ep_conf_s *ep)
{
struct napi_struct *napi = NULL;
gro_result_t gro_res;
trace___rmnet_deliver_skb(skb);
switch (ep->rmnet_mode) {
case RMNET_EPMODE_NONE:
@ -193,7 +210,20 @@ static rx_handler_result_t __rmnet_deliver_skb(struct sk_buff *skb,
case RX_HANDLER_PASS:
skb->pkt_type = PACKET_HOST;
netif_receive_skb(skb);
rmnet_reset_mac_header(skb);
if (skb->dev->features & NETIF_F_GRO) {
napi = get_current_napi_context();
if (napi != NULL) {
gro_res = napi_gro_receive(napi, skb);
trace_rmnet_gro_downlink(skb->dev,
gro_res);
} else {
WARN_ONCE(1, "current napi is NULL\n");
netif_receive_skb(skb);
}
} else {
netif_receive_skb(skb);
}
return RX_HANDLER_CONSUMED;
}
return RX_HANDLER_PASS;
@ -304,7 +334,6 @@ static rx_handler_result_t _rmnet_map_ingress_handler(struct sk_buff *skb,
skb_pull(skb, sizeof(struct rmnet_map_header_s));
skb_trim(skb, len);
__rmnet_data_set_skb_proto(skb);
return __rmnet_deliver_skb(skb, ep);
}

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@ -305,6 +305,27 @@ DEFINE_EVENT(rmnet_physdev_action_template, rmnet_unassociate,
TP_ARGS(dev)
);
TRACE_EVENT(rmnet_gro_downlink,
TP_PROTO(struct net_device *dev, gro_result_t gro_res),
TP_ARGS(dev, gro_res),
TP_STRUCT__entry(
__string(name, dev->name)
__field(gro_result_t, res)
),
TP_fast_assign(
__assign_str(name, dev->name);
__entry->res = gro_res;
),
TP_printk("GRO on dev=%s, res: %d",
__get_str(name), __entry->res)
)
#endif /* _RMNET_DATA_TRACE_H_ */
/* This part must be outside protection */

View File

@ -593,6 +593,8 @@ int rmnet_vnd_create_dev(int id, struct net_device **new_device,
/* Configuring UL checksum offload on rmnet_data interfaces */
dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
NETIF_F_IPV6_UDP_CSUM;
/* Configuring GRO on rmnet_data interfaces */
dev->hw_features = NETIF_F_GRO;
}
rc = register_netdevice(dev);