Patchwork [net-next,V2,2/3] xen-netback: avoid allocating variable size array on stack

login
register
mail settings
Submitter Wei Liu
Date May 2, 2013, 10:43 a.m.
Message ID <1367491439-27629-3-git-send-email-wei.liu2@citrix.com>
Download mbox | patch
Permalink /patch/240935/
State Accepted
Delegated to: David Miller
Headers show

Comments

Wei Liu - May 2, 2013, 10:43 a.m.
Tune xen_netbk_count_requests to not touch working array beyond limit, so that
we can make working array size constant.

Suggested-by: Jan Beulich <jbeulich@suse.com>
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
---
 drivers/net/xen-netback/netback.c |   16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)
Jan Beulich - May 2, 2013, 12:04 p.m.
>>> On 02.05.13 at 12:43, Wei Liu <wei.liu2@citrix.com> wrote:
> @@ -934,11 +934,14 @@ static int netbk_count_requests(struct xenvif *vif,
>  	RING_IDX cons = vif->tx.req_cons;
>  	int slots = 0;
>  	int drop_err = 0;
> +	int more_data;
>  
>  	if (!(first->flags & XEN_NETTXF_more_data))
>  		return 0;
>  
>  	do {
> +		struct xen_netif_tx_request dropped_tx = { 0 };
> +

No need for an initializer here.

>  		if (slots >= work_to_do) {
>  			netdev_err(vif->dev,
>  				   "Asked for %d slots but exceeds this limit\n",
> @@ -972,6 +975,9 @@ static int netbk_count_requests(struct xenvif *vif,
>  			drop_err = -E2BIG;
>  		}
>  
> +		if (drop_err)
> +			txp = &dropped_tx;
> +
>  		memcpy(txp, RING_GET_REQUEST(&vif->tx, cons + slots),
>  		       sizeof(*txp));
>  
> @@ -1001,7 +1007,13 @@ static int netbk_count_requests(struct xenvif *vif,
>  			netbk_fatal_tx_err(vif);
>  			return -EINVAL;
>  		}
> -	} while ((txp++)->flags & XEN_NETTXF_more_data);
> +
> +		more_data = txp->flags & XEN_NETTXF_more_data;
> +
> +		if (!drop_err)
> +			txp++;

And no need for the conditional here afaict.

Jan

> +
> +	} while (more_data);
>  
>  	if (drop_err) {
>  		netbk_tx_err(vif, first, cons + slots);


--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Ian Campbell - May 2, 2013, 3:55 p.m.
On Thu, 2013-05-02 at 13:04 +0100, Jan Beulich wrote:
> >>> On 02.05.13 at 12:43, Wei Liu <wei.liu2@citrix.com> wrote:
> > @@ -934,11 +934,14 @@ static int netbk_count_requests(struct xenvif *vif,
> >  	RING_IDX cons = vif->tx.req_cons;
> >  	int slots = 0;
> >  	int drop_err = 0;
> > +	int more_data;
> >  
> >  	if (!(first->flags & XEN_NETTXF_more_data))
> >  		return 0;
> >  
> >  	do {
> > +		struct xen_netif_tx_request dropped_tx = { 0 };
> > +
> 
> No need for an initializer here.
> 
> >  		if (slots >= work_to_do) {
> >  			netdev_err(vif->dev,
> >  				   "Asked for %d slots but exceeds this limit\n",
> > @@ -972,6 +975,9 @@ static int netbk_count_requests(struct xenvif *vif,
> >  			drop_err = -E2BIG;
> >  		}
> >  
> > +		if (drop_err)
> > +			txp = &dropped_tx;
> > +
> >  		memcpy(txp, RING_GET_REQUEST(&vif->tx, cons + slots),
> >  		       sizeof(*txp));
> >  
> > @@ -1001,7 +1007,13 @@ static int netbk_count_requests(struct xenvif *vif,
> >  			netbk_fatal_tx_err(vif);
> >  			return -EINVAL;
> >  		}
> > -	} while ((txp++)->flags & XEN_NETTXF_more_data);
> > +
> > +		more_data = txp->flags & XEN_NETTXF_more_data;
> > +
> > +		if (!drop_err)
> > +			txp++;
> 
> And no need for the conditional here afaict.

I think it is needed, in the case where you've assigned txp =
&dropped_tx you don't want to increment txp.

Or perhaps it just gets reassigned back to &dropped_tx at the top of the
next loop, so the increment doesn't matter. Subtle! I'm happy with
whichever way Wei prefers, but it is probably worthy of a comment

> 
> Jan
> 
> > +
> > +	} while (more_data);
> >  
> >  	if (drop_err) {
> >  		netbk_tx_err(vif, first, cons + slots);
> 
> 


--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Wei Liu - May 2, 2013, 4 p.m.
On Thu, May 02, 2013 at 04:55:46PM +0100, Ian Campbell wrote:
> > > +		more_data = txp->flags & XEN_NETTXF_more_data;
> > > +
> > > +		if (!drop_err)
> > > +			txp++;
> > 
> > And no need for the conditional here afaict.
> 
> I think it is needed, in the case where you've assigned txp =
> &dropped_tx you don't want to increment txp.
> 
> Or perhaps it just gets reassigned back to &dropped_tx at the top of the
> next loop, so the increment doesn't matter. Subtle! I'm happy with
> whichever way Wei prefers, but it is probably worthy of a comment
> 

Yes that's my starting point. I know that txp will always be assigned to
&dropped_tx, I just don't feel comfortable incrementing txp in that
case.

This is really a personal taste thing. :-)


Wei.
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Patch

diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c
index c44772d..ce8109f 100644
--- a/drivers/net/xen-netback/netback.c
+++ b/drivers/net/xen-netback/netback.c
@@ -934,11 +934,14 @@  static int netbk_count_requests(struct xenvif *vif,
 	RING_IDX cons = vif->tx.req_cons;
 	int slots = 0;
 	int drop_err = 0;
+	int more_data;
 
 	if (!(first->flags & XEN_NETTXF_more_data))
 		return 0;
 
 	do {
+		struct xen_netif_tx_request dropped_tx = { 0 };
+
 		if (slots >= work_to_do) {
 			netdev_err(vif->dev,
 				   "Asked for %d slots but exceeds this limit\n",
@@ -972,6 +975,9 @@  static int netbk_count_requests(struct xenvif *vif,
 			drop_err = -E2BIG;
 		}
 
+		if (drop_err)
+			txp = &dropped_tx;
+
 		memcpy(txp, RING_GET_REQUEST(&vif->tx, cons + slots),
 		       sizeof(*txp));
 
@@ -1001,7 +1007,13 @@  static int netbk_count_requests(struct xenvif *vif,
 			netbk_fatal_tx_err(vif);
 			return -EINVAL;
 		}
-	} while ((txp++)->flags & XEN_NETTXF_more_data);
+
+		more_data = txp->flags & XEN_NETTXF_more_data;
+
+		if (!drop_err)
+			txp++;
+
+	} while (more_data);
 
 	if (drop_err) {
 		netbk_tx_err(vif, first, cons + slots);
@@ -1408,7 +1420,7 @@  static unsigned xen_netbk_tx_build_gops(struct xen_netbk *netbk)
 		!list_empty(&netbk->net_schedule_list)) {
 		struct xenvif *vif;
 		struct xen_netif_tx_request txreq;
-		struct xen_netif_tx_request txfrags[max_skb_slots];
+		struct xen_netif_tx_request txfrags[XEN_NETIF_NR_SLOTS_MIN];
 		struct page *page;
 		struct xen_netif_extra_info extras[XEN_NETIF_EXTRA_TYPE_MAX-1];
 		u16 pending_idx;