diff options
Diffstat (limited to 'drivers/rmnet/shs/rmnet_shs_main.c')
-rwxr-xr-x | drivers/rmnet/shs/rmnet_shs_main.c | 23 |
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; } |