diff options
author | Claudiu Manoil <claudiu.manoil@freescale.com> | 2013-07-17 10:40:54 (GMT) |
---|---|---|
committer | Fleming Andrew-AFLEMING <AFLEMING@freescale.com> | 2013-07-22 22:00:50 (GMT) |
commit | 1f4adc0a9a01b72eea5bf38fe9f6a934b2f90ce4 (patch) | |
tree | d4483ee8b45f5bdfde27388fb46ac8a12a07f49d /drivers/net/ethernet/freescale | |
parent | 65667541a3908d2e8268a927e3aa7c7098f31ce1 (diff) | |
download | linux-fsl-qoriq-1f4adc0a9a01b72eea5bf38fe9f6a934b2f90ce4.tar.xz |
gianfar: Fix illegal access when skb recycling disabled
When the skb recycling feature is disabled via module param
(gfar_skb_recycling_en), rec->local is being accessed while
not initialized.
Signed-off-by: Claudiu Manoil <claudiu.manoil@freescale.com>
Change-Id: I0f9d355302e694860cc3d46c296409126887b4a9
Reviewed-on: http://git.am.freescale.net:8181/3369
Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com>
Reviewed-by: Fleming Andrew-AFLEMING <AFLEMING@freescale.com>
Diffstat (limited to 'drivers/net/ethernet/freescale')
-rw-r--r-- | drivers/net/ethernet/freescale/gianfar.c | 7 | ||||
-rw-r--r-- | drivers/net/ethernet/freescale/gianfar_sysfs.c | 3 |
2 files changed, 10 insertions, 0 deletions
diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c index a53231c..eb60e10 100644 --- a/drivers/net/ethernet/freescale/gianfar.c +++ b/drivers/net/ethernet/freescale/gianfar.c @@ -1153,6 +1153,7 @@ static void gfar_init_recycle(struct gfar_private *priv) rec->buff_size = priv->rx_buffer_size + RXBUF_ALIGNMENT; skb_queue_head_init(&rec->recycle_q); + rec->local = NULL; if (!gfar_skb_recycling_en) goto disable_rec; @@ -2141,6 +2142,9 @@ static void free_skb_recycle_q(struct gfar_priv_recycle *rec) while ((skb = skb_dequeue(&rec->recycle_q)) != NULL) dev_kfree_skb_any(skb); + if (!rec->local) + return; + for_each_possible_cpu(cpu) { struct gfar_priv_recycle_local *local; @@ -3490,6 +3494,9 @@ static struct sk_buff *gfar_new_skb(struct gfar_private *priv) struct sk_buff_head *recycle_q; int cpu; + if (unlikely(!rec->local)) + goto alloc; + cpu = get_cpu(); local = per_cpu_ptr(rec->local, cpu); skb = __skb_dequeue(&local->recycle_q); diff --git a/drivers/net/ethernet/freescale/gianfar_sysfs.c b/drivers/net/ethernet/freescale/gianfar_sysfs.c index 83d725b..b9c1641 100644 --- a/drivers/net/ethernet/freescale/gianfar_sysfs.c +++ b/drivers/net/ethernet/freescale/gianfar_sysfs.c @@ -375,6 +375,9 @@ static ssize_t gfar_show_recycle(struct device *dev, for_each_possible_cpu(cpu) { struct gfar_priv_recycle_local *local; + if (!rec->local) + break; + local = per_cpu_ptr(rec->local, cpu); pr_info("local: CPU#%d: recycled skbs %d, reused skbs %d\n", cpu, local->recycle_cnt, local->reuse_cnt); |