summaryrefslogtreecommitdiff
path: root/drivers/rmnet/shs/rmnet_shs_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/rmnet/shs/rmnet_shs_main.c')
-rwxr-xr-xdrivers/rmnet/shs/rmnet_shs_main.c23
1 files changed, 14 insertions, 9 deletions
diff --git a/drivers/rmnet/shs/rmnet_shs_main.c b/drivers/rmnet/shs/rmnet_shs_main.c
index dec38c4..8d9ed2b 100755
--- a/drivers/rmnet/shs/rmnet_shs_main.c
+++ b/drivers/rmnet/shs/rmnet_shs_main.c
@@ -404,6 +404,7 @@ static struct sk_buff *rmnet_shs_skb_partial_segment(struct sk_buff *skb,
struct sk_buff *segments, *tmp;
u16 gso_size = shinfo->gso_size;
u16 gso_segs = shinfo->gso_segs;
+ unsigned int gso_type = shinfo->gso_type;
if (segments_per_skb >= gso_segs) {
return NULL;
@@ -420,15 +421,19 @@ static struct sk_buff *rmnet_shs_skb_partial_segment(struct sk_buff *skb,
return NULL;
}
- /* Mark correct number of segments and correct size in the new skbs */
+ /* Mark correct number of segments, size, and type in the new skbs */
for (tmp = segments; tmp; tmp = tmp->next) {
struct skb_shared_info *new_shinfo = skb_shinfo(tmp);
- new_shinfo->gso_size = gso_size;
- if (gso_segs >= segments_per_skb)
- new_shinfo->gso_segs = segments_per_skb;
- else
- new_shinfo->gso_segs = gso_segs;
+ if (tmp->len > gso_size) {
+ new_shinfo->gso_type = gso_type;
+ new_shinfo->gso_size = gso_size;
+
+ if (gso_segs >= segments_per_skb)
+ new_shinfo->gso_segs = segments_per_skb;
+ else
+ new_shinfo->gso_segs = gso_segs;
+ }
gso_segs -= segments_per_skb;
}
@@ -1012,6 +1017,8 @@ void rmnet_shs_flush_node(struct rmnet_shs_skbn_s *node, u8 ctext)
skb_bytes_delivered += skb->len;
if (segs_per_skb > 0) {
+ if (node->skb_tport_proto == IPPROTO_UDP)
+ rmnet_shs_crit_err[RMNET_SHS_UDP_SEGMENT]++;
rmnet_shs_deliver_skb_segmented(skb, ctext,
segs_per_skb);
} else {
@@ -1511,7 +1518,7 @@ int rmnet_shs_drop_backlog(struct sk_buff_head *list, int cpu)
return 0;
}
-
+/* This will run in process context, avoid disabling bh */
static int rmnet_shs_oom_notify(struct notifier_block *self,
unsigned long emtpy, void *free)
{
@@ -1520,7 +1527,6 @@ static int rmnet_shs_oom_notify(struct notifier_block *self,
struct sk_buff_head *process_q;
struct sk_buff_head *input_q;
- local_bh_disable();
for_each_possible_cpu(cpu) {
process_q = &GET_PQUEUE(cpu);
@@ -1541,7 +1547,6 @@ static int rmnet_shs_oom_notify(struct notifier_block *self,
(*nfree)++;
}
}
- local_bh_enable();
return 0;
}