* [RFC] skb truesize last offenders @ 2012-03-23 12:51 Eric Dumazet 2012-03-23 18:38 ` David Miller 0 siblings, 1 reply; 8+ messages in thread From: Eric Dumazet @ 2012-03-23 12:51 UTC (permalink / raw) To: David Miller; +Cc: netdev, Wey-Yi Guy iwlwifi and some other users of skb_add_rx_frag() lie about skb truesize, because of API being lazy. iwlwifi can use order-0 or order-1 pages and skb truesize is wrong. network sbs can use uncharged kernel memory and eventually crash machine in OOM. I plan : 1) adding a @truesize parameter to skb_add_rx_frag() in a neutral patch 2) fix drivers that dont charge the real size of fragment 3) niu could then use skb_add_rx_frag() instead of custom code. ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [RFC] skb truesize last offenders 2012-03-23 12:51 [RFC] skb truesize last offenders Eric Dumazet @ 2012-03-23 18:38 ` David Miller 2012-03-23 18:55 ` Eric Dumazet 0 siblings, 1 reply; 8+ messages in thread From: David Miller @ 2012-03-23 18:38 UTC (permalink / raw) To: eric.dumazet; +Cc: netdev, wey-yi.w.guy From: Eric Dumazet <eric.dumazet@gmail.com> Date: Fri, 23 Mar 2012 05:51:52 -0700 > iwlwifi and some other users of skb_add_rx_frag() lie about skb > truesize, because of API being lazy. > > iwlwifi can use order-0 or order-1 pages and skb truesize is wrong. > network sbs can use uncharged kernel memory and eventually crash machine > in OOM. > > I plan : > > 1) adding a @truesize parameter to skb_add_rx_frag() in a neutral patch > > 2) fix drivers that dont charge the real size of fragment > > 3) niu could then use skb_add_rx_frag() instead of custom code. No objections from me. But we really have to fix that tcp_grow_window() issue, it's quite urgent if you ask me. ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [RFC] skb truesize last offenders 2012-03-23 18:38 ` David Miller @ 2012-03-23 18:55 ` Eric Dumazet 2012-03-24 0:05 ` [PATCH] iwlwifi: fix skb truesize underestimation Eric Dumazet 0 siblings, 1 reply; 8+ messages in thread From: Eric Dumazet @ 2012-03-23 18:55 UTC (permalink / raw) To: David Miller; +Cc: netdev, wey-yi.w.guy, Neal Cardwell On Fri, 2012-03-23 at 14:38 -0400, David Miller wrote: > From: Eric Dumazet <eric.dumazet@gmail.com> > Date: Fri, 23 Mar 2012 05:51:52 -0700 > > > iwlwifi and some other users of skb_add_rx_frag() lie about skb > > truesize, because of API being lazy. > > > > iwlwifi can use order-0 or order-1 pages and skb truesize is wrong. > > network sbs can use uncharged kernel memory and eventually crash machine > > in OOM. > > > > I plan : > > > > 1) adding a @truesize parameter to skb_add_rx_frag() in a neutral patch > > > > 2) fix drivers that dont charge the real size of fragment > > > > 3) niu could then use skb_add_rx_frag() instead of custom code. > > No objections from me. But we really have to fix that > tcp_grow_window() issue, it's quite urgent if you ask me. Sure, I can work on this issue with Neal asap, we do have some ideas on this subject. ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH] iwlwifi: fix skb truesize underestimation 2012-03-23 18:55 ` Eric Dumazet @ 2012-03-24 0:05 ` Eric Dumazet 2012-03-24 0:22 ` Eric Dumazet 0 siblings, 1 reply; 8+ messages in thread From: Eric Dumazet @ 2012-03-24 0:05 UTC (permalink / raw) To: David Miller; +Cc: netdev, wey-yi.w.guy, Neal Cardwell, John W. Linville By default, iwlwifi uses order-1 pages (8 KB) to store incoming frames, but doesnt say so in skb->truesize. This makes very possible to exhaust kernel memory since these skb evade normal socket memory accounting. As struct ieee80211_hdr is going to be pulled before calling IP stack, there is no need to use dev_alloc_skb() to reserve NET_SKB_PAD bytes. alloc_skb() is ok in this driver, allowing more tailroom. Pull beginning of frame in skb header, in the hope we can reuse order-1 pages in the driver immediately for small frames and reduce their truesize to the minimum (linear skbs) Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com> Cc: Wey-Yi Guy <wey-yi.w.guy@intel.com> Cc: "John W. Linville" <linville@tuxdriver.com> Cc: Neal Cardwell <ncardwell@google.com> --- Depends on the "net: add a truesize parameter to skb_add_rx_frag()" prior patch. drivers/net/wireless/iwlwifi/iwl-agn-rx.c | 25 ++++++++----- drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c | 3 + drivers/net/wireless/iwlwifi/iwl-trans.h | 1 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c index f4b84d1..9ecd768f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c @@ -773,8 +773,7 @@ static void iwlagn_pass_packet_to_mac80211(struct iwl_priv *priv, struct sk_buff *skb; __le16 fc = hdr->frame_control; struct iwl_rxon_context *ctx; - struct page *p; - int offset; + unsigned int hdrlen; /* We only process data packets if the interface is open */ if (unlikely(!priv->is_open)) { @@ -788,16 +787,24 @@ static void iwlagn_pass_packet_to_mac80211(struct iwl_priv *priv, iwlagn_set_decrypted_flag(priv, hdr, ampdu_status, stats)) return; - skb = dev_alloc_skb(128); + /* Dont use dev_alloc_skb(), we'll have enough headroom once + * ieee80211_hdr pulled. + */ + skb = alloc_skb(128); if (!skb) { - IWL_ERR(priv, "dev_alloc_skb failed\n"); + IWL_ERR(priv, "alloc_skb failed\n"); return; } - - offset = (void *)hdr - rxb_addr(rxb); - p = rxb_steal_page(rxb); - skb_add_rx_frag(skb, 0, p, offset, len, len); - + hdrlen = min_t(unsigned int, len, skb_tailroom(skb)); + memcpy(skb_put(skb, hdrlen), hdr, hdrlen); + len -= hdrlen; + + if (len) { + int offset = (void *)hdr + hdrlen - rxb_addr(rxb); + + skb_add_rx_frag(skb, 0, rxb_steal_page(rxb), offset, + len, rxb->truesize); + } iwl_update_stats(priv, false, fc, len); /* diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c index 8b1a798..aa7aea1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c @@ -374,8 +374,9 @@ static void iwl_rx_handle_rxbuf(struct iwl_trans *trans, if (WARN_ON(!rxb)) return; + rxcb.truesize = PAGE_SIZE << hw_params(trans).rx_page_order; dma_unmap_page(trans->dev, rxb->page_dma, - PAGE_SIZE << hw_params(trans).rx_page_order, + rxcb.truesize, DMA_FROM_DEVICE); rxcb._page = rxb->page; diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 0c81cba..fdf9788 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -260,6 +260,7 @@ static inline void iwl_free_resp(struct iwl_host_cmd *cmd) struct iwl_rx_cmd_buffer { struct page *_page; + unsigned int truesize; }; static inline void *rxb_addr(struct iwl_rx_cmd_buffer *r) ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH] iwlwifi: fix skb truesize underestimation 2012-03-24 0:05 ` [PATCH] iwlwifi: fix skb truesize underestimation Eric Dumazet @ 2012-03-24 0:22 ` Eric Dumazet 2012-03-24 0:29 ` [PATCH v2] " Eric Dumazet 0 siblings, 1 reply; 8+ messages in thread From: Eric Dumazet @ 2012-03-24 0:22 UTC (permalink / raw) To: David Miller; +Cc: netdev, wey-yi.w.guy, Neal Cardwell, John W. Linville On Fri, 2012-03-23 at 17:05 -0700, Eric Dumazet wrote: > + if (len) { > + int offset = (void *)hdr + hdrlen - rxb_addr(rxb); > + > + skb_add_rx_frag(skb, 0, rxb_steal_page(rxb), offset, > + len, rxb->truesize); > + } > iwl_update_stats(priv, false, fc, len); > Please delete this patch, I'll send a v2 : iwl_update_stats() should be called with original "len", not "len - hdrlen" ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v2] iwlwifi: fix skb truesize underestimation 2012-03-24 0:22 ` Eric Dumazet @ 2012-03-24 0:29 ` Eric Dumazet 2012-03-24 15:35 ` Guy, Wey-Yi 0 siblings, 1 reply; 8+ messages in thread From: Eric Dumazet @ 2012-03-24 0:29 UTC (permalink / raw) To: David Miller; +Cc: netdev, wey-yi.w.guy, Neal Cardwell, John W. Linville By default, iwlwifi uses order-1 pages (8 KB) to store incoming frames, but doesnt say so in skb->truesize. This makes very possible to exhaust kernel memory since these skb evade normal socket memory accounting. As struct ieee80211_hdr is going to be pulled before calling IP stack, there is no need to use dev_alloc_skb() to reserve NET_SKB_PAD bytes. alloc_skb() is ok in this driver, allowing more tailroom. Pull beginning of frame in skb header, in the hope we can reuse order-1 pages in the driver immediately for small frames and reduce their truesize to the minimum (linear skbs) Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com> Cc: Wey-Yi Guy <wey-yi.w.guy@intel.com> Cc: "John W. Linville" <linville@tuxdriver.com> Cc: Neal Cardwell <ncardwell@google.com> --- Depends on the "net: add a truesize parameter to skb_add_rx_frag()" prior patch. v2: fix the iwl_update_stats() call drivers/net/wireless/iwlwifi/iwl-agn-rx.c | 25 ++++++++----- drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c | 3 + drivers/net/wireless/iwlwifi/iwl-trans.h | 1 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c index f4b84d1..19a9499 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c @@ -773,8 +773,7 @@ static void iwlagn_pass_packet_to_mac80211(struct iwl_priv *priv, struct sk_buff *skb; __le16 fc = hdr->frame_control; struct iwl_rxon_context *ctx; - struct page *p; - int offset; + unsigned int hdrlen, fraglen; /* We only process data packets if the interface is open */ if (unlikely(!priv->is_open)) { @@ -788,16 +787,24 @@ static void iwlagn_pass_packet_to_mac80211(struct iwl_priv *priv, iwlagn_set_decrypted_flag(priv, hdr, ampdu_status, stats)) return; - skb = dev_alloc_skb(128); + /* Dont use dev_alloc_skb(), we'll have enough headroom once + * ieee80211_hdr pulled. + */ + skb = alloc_skb(128, GFP_ATOMIC); if (!skb) { - IWL_ERR(priv, "dev_alloc_skb failed\n"); + IWL_ERR(priv, "alloc_skb failed\n"); return; } - - offset = (void *)hdr - rxb_addr(rxb); - p = rxb_steal_page(rxb); - skb_add_rx_frag(skb, 0, p, offset, len, len); - + hdrlen = min_t(unsigned int, len, skb_tailroom(skb)); + memcpy(skb_put(skb, hdrlen), hdr, hdrlen); + fraglen = len - hdrlen; + + if (fraglen) { + int offset = (void *)hdr + hdrlen - rxb_addr(rxb); + + skb_add_rx_frag(skb, 0, rxb_steal_page(rxb), offset, + fraglen, rxb->truesize); + } iwl_update_stats(priv, false, fc, len); /* diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c index 8b1a798..aa7aea1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c @@ -374,8 +374,9 @@ static void iwl_rx_handle_rxbuf(struct iwl_trans *trans, if (WARN_ON(!rxb)) return; + rxcb.truesize = PAGE_SIZE << hw_params(trans).rx_page_order; dma_unmap_page(trans->dev, rxb->page_dma, - PAGE_SIZE << hw_params(trans).rx_page_order, + rxcb.truesize, DMA_FROM_DEVICE); rxcb._page = rxb->page; diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 0c81cba..fdf9788 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -260,6 +260,7 @@ static inline void iwl_free_resp(struct iwl_host_cmd *cmd) struct iwl_rx_cmd_buffer { struct page *_page; + unsigned int truesize; }; static inline void *rxb_addr(struct iwl_rx_cmd_buffer *r) ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v2] iwlwifi: fix skb truesize underestimation 2012-03-24 0:29 ` [PATCH v2] " Eric Dumazet @ 2012-03-24 15:35 ` Guy, Wey-Yi 2012-03-24 16:12 ` Eric Dumazet 0 siblings, 1 reply; 8+ messages in thread From: Guy, Wey-Yi @ 2012-03-24 15:35 UTC (permalink / raw) To: Eric Dumazet; +Cc: David Miller, netdev, Neal Cardwell, John W. Linville Hi Eric, On Fri, 2012-03-23 at 17:29 -0700, Eric Dumazet wrote: > By default, iwlwifi uses order-1 pages (8 KB) to store incoming frames, > but doesnt say so in skb->truesize. > > This makes very possible to exhaust kernel memory since these skb evade > normal socket memory accounting. > > As struct ieee80211_hdr is going to be pulled before calling IP stack, > there is no need to use dev_alloc_skb() to reserve NET_SKB_PAD bytes. > alloc_skb() is ok in this driver, allowing more tailroom. > > Pull beginning of frame in skb header, in the hope we can reuse order-1 > pages in the driver immediately for small frames and reduce their > truesize to the minimum (linear skbs) > > Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com> > Cc: Wey-Yi Guy <wey-yi.w.guy@intel.com> > Cc: "John W. Linville" <linville@tuxdriver.com> > Cc: Neal Cardwell <ncardwell@google.com> > --- Is it ok I pull your patch into our internal tree first for regression testing, once the test is done, I will push your patch along with all our other patches together to wireless-next(John Linville). By doing so, first, we know the patch is not breaking any functionality for all the devices(legacy/new), second, it is easier for us to sync-up with all the other changes we are making now. Thanks Wey ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2] iwlwifi: fix skb truesize underestimation 2012-03-24 15:35 ` Guy, Wey-Yi @ 2012-03-24 16:12 ` Eric Dumazet 0 siblings, 0 replies; 8+ messages in thread From: Eric Dumazet @ 2012-03-24 16:12 UTC (permalink / raw) To: Guy, Wey-Yi; +Cc: David Miller, netdev, Neal Cardwell, John W. Linville Le samedi 24 mars 2012 à 08:35 -0700, Guy, Wey-Yi a écrit : > Hi Eric, > > On Fri, 2012-03-23 at 17:29 -0700, Eric Dumazet wrote: > > By default, iwlwifi uses order-1 pages (8 KB) to store incoming frames, > > but doesnt say so in skb->truesize. > > > > This makes very possible to exhaust kernel memory since these skb evade > > normal socket memory accounting. > > > > As struct ieee80211_hdr is going to be pulled before calling IP stack, > > there is no need to use dev_alloc_skb() to reserve NET_SKB_PAD bytes. > > alloc_skb() is ok in this driver, allowing more tailroom. > > > > Pull beginning of frame in skb header, in the hope we can reuse order-1 > > pages in the driver immediately for small frames and reduce their > > truesize to the minimum (linear skbs) > > > > Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com> > > Cc: Wey-Yi Guy <wey-yi.w.guy@intel.com> > > Cc: "John W. Linville" <linville@tuxdriver.com> > > Cc: Neal Cardwell <ncardwell@google.com> > > --- > > Is it ok I pull your patch into our internal tree first for regression > testing, once the test is done, I will push your patch along with all > our other patches together to wireless-next(John Linville). > > By doing so, first, we know the patch is not breaking any functionality > for all the devices(legacy/new), second, it is easier for us to sync-up > with all the other changes we are making now. > I am absolutely fine with this plan, thanks a lot ! BTW, why order-1 pages are the default on this driver ? ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2012-03-24 16:12 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2012-03-23 12:51 [RFC] skb truesize last offenders Eric Dumazet 2012-03-23 18:38 ` David Miller 2012-03-23 18:55 ` Eric Dumazet 2012-03-24 0:05 ` [PATCH] iwlwifi: fix skb truesize underestimation Eric Dumazet 2012-03-24 0:22 ` Eric Dumazet 2012-03-24 0:29 ` [PATCH v2] " Eric Dumazet 2012-03-24 15:35 ` Guy, Wey-Yi 2012-03-24 16:12 ` Eric Dumazet
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox