From: Jiri Benc <jbenc@suse.cz>
To: netdev@vger.kernel.org
Subject: [PATCH 6/9] d80211: optimize defragmentation
Date: Tue, 18 Jul 2006 17:45:27 +0200 (CEST) [thread overview]
Message-ID: <20060718154527.11F28483BB@silver.suse.cz> (raw)
In-Reply-To: <20060718174442.485760904.midnight@suse.cz>
Optimize defragmentation by storing all fragments in skb queue and
reallocating skb only once all fragments are received.
Signed-off-by: Jiri Benc <jbenc@suse.cz>
---
net/d80211/ieee80211.c | 46 ++++++++++++++++++++++--------------------
net/d80211/ieee80211_i.h | 3 ++-
net/d80211/ieee80211_iface.c | 19 ++++++++++++++---
3 files changed, 41 insertions(+), 27 deletions(-)
162a9ab0920090224f0af03b4a79b45b35dd437f
diff --git a/net/d80211/ieee80211.c b/net/d80211/ieee80211.c
index ac2c03f..cc06675 100644
--- a/net/d80211/ieee80211.c
+++ b/net/d80211/ieee80211.c
@@ -2822,10 +2822,10 @@ ieee80211_reassemble_add(struct ieee8021
if (sdata->fragment_next >= IEEE80211_FRAGMENT_MAX)
sdata->fragment_next = 0;
- if (entry->skb) {
+ if (!skb_queue_empty(&entry->skb_list)) {
#ifdef CONFIG_D80211_DEBUG
struct ieee80211_hdr *hdr =
- (struct ieee80211_hdr *) entry->skb->data;
+ (struct ieee80211_hdr *) entry->skb_list.next->data;
printk(KERN_DEBUG "%s: RX reassembly removed oldest "
"fragment entry (idx=%d age=%lu seq=%d last_frag=%d "
"addr1=" MACSTR " addr2=" MACSTR "\n",
@@ -2834,16 +2834,17 @@ #ifdef CONFIG_D80211_DEBUG
entry->last_frag, MAC2STR(hdr->addr1),
MAC2STR(hdr->addr2));
#endif /* CONFIG_D80211_DEBUG */
- dev_kfree_skb(entry->skb);
+ __skb_queue_purge(&entry->skb_list);
}
- entry->skb = *skb;
+ __skb_queue_tail(&entry->skb_list, *skb); /* no need for locking */
*skb = NULL;
entry->first_frag_time = jiffies;
entry->seq = seq;
entry->rx_queue = rx_queue;
entry->last_frag = frag;
entry->ccmp = 0;
+ entry->extra_len = 0;
return entry;
}
@@ -2867,12 +2868,12 @@ ieee80211_reassemble_find(struct ieee802
idx = IEEE80211_FRAGMENT_MAX - 1;
entry = &sdata->fragments[idx];
- if (!entry->skb || entry->seq != seq ||
+ if (skb_queue_empty(&entry->skb_list) || entry->seq != seq ||
entry->rx_queue != rx_queue ||
entry->last_frag + 1 != frag)
continue;
- f_hdr = (struct ieee80211_hdr *) entry->skb->data;
+ f_hdr = (struct ieee80211_hdr *) entry->skb_list.next->data;
f_fc = le16_to_cpu(f_hdr->frame_control);
if (WLAN_FC_GET_TYPE(fc) != WLAN_FC_GET_TYPE(f_fc) ||
@@ -2881,8 +2882,7 @@ ieee80211_reassemble_find(struct ieee802
continue;
if (entry->first_frag_time + 2 * HZ < jiffies) {
- dev_kfree_skb(entry->skb);
- entry->skb = NULL;
+ __skb_queue_purge(&entry->skb_list);
continue;
}
return entry;
@@ -2899,6 +2899,7 @@ ieee80211_rx_h_defragment(struct ieee802
u16 sc;
unsigned int frag, seq;
struct ieee80211_fragment_entry *entry;
+ struct sk_buff *skb;
hdr = (struct ieee80211_hdr *) rx->skb->data;
sc = le16_to_cpu(hdr->seq_ctrl);
@@ -2966,30 +2967,30 @@ ieee80211_rx_h_defragment(struct ieee802
memcpy(entry->last_pn, pn, CCMP_PN_LEN);
}
- /* TODO: could gather list of skb's and reallocate data buffer only
- * after finding out the total length of the frame */
skb_pull(rx->skb, ieee80211_get_hdrlen(rx->fc));
- if (skb_tailroom(entry->skb) < rx->skb->len) {
+ __skb_queue_tail(&entry->skb_list, rx->skb);
+ entry->last_frag = frag;
+ entry->extra_len += rx->skb->len;
+ if (rx->fc & WLAN_FC_MOREFRAG) {
+ rx->skb = NULL;
+ return TXRX_QUEUED;
+ }
+
+ rx->skb = __skb_dequeue(&entry->skb_list);
+ if (skb_tailroom(rx->skb) < entry->extra_len) {
I802_DEBUG_INC(rx->local->rx_expand_skb_head2);
- if (unlikely(pskb_expand_head(entry->skb, 0, rx->skb->len,
+ if (unlikely(pskb_expand_head(rx->skb, 0, entry->extra_len,
GFP_ATOMIC))) {
I802_DEBUG_INC(rx->local->rx_handlers_drop_defrag);
+ __skb_queue_purge(&entry->skb_list);
return TXRX_DROP;
}
}
- memcpy(skb_put(entry->skb, rx->skb->len), rx->skb->data, rx->skb->len);
- entry->last_frag = frag;
- dev_kfree_skb(rx->skb);
-
- if (rx->fc & WLAN_FC_MOREFRAG) {
- rx->skb = NULL;
- return TXRX_QUEUED;
- }
+ while ((skb = __skb_dequeue(&entry->skb_list)))
+ memcpy(skb_put(rx->skb, skb->len), skb->data, skb->len);
/* Complete frame has been reassembled - process it now */
- rx->skb = entry->skb;
rx->fragmented = 1;
- entry->skb = NULL;
out:
if (rx->sta)
@@ -4390,6 +4391,7 @@ struct net_device *ieee80211_alloc_hw(si
sdata->dev = mdev;
sdata->master = mdev;
sdata->local = local;
+ ieee80211_if_sdata_init(sdata);
list_add_tail(&sdata->list, &local->sub_if_list);
tasklet_init(&local->tx_pending_tasklet, ieee80211_tx_pending,
diff --git a/net/d80211/ieee80211_i.h b/net/d80211/ieee80211_i.h
index 6a952bd..b4e294c 100644
--- a/net/d80211/ieee80211_i.h
+++ b/net/d80211/ieee80211_i.h
@@ -62,7 +62,8 @@ struct ieee80211_fragment_entry {
unsigned int seq;
unsigned int rx_queue;
unsigned int last_frag;
- struct sk_buff *skb;
+ unsigned int extra_len;
+ struct sk_buff_head skb_list;
int ccmp; /* Whether fragments were encrypted with CCMP */
u8 last_pn[6]; /* PN of the last fragment if CCMP was used */
};
diff --git a/net/d80211/ieee80211_iface.c b/net/d80211/ieee80211_iface.c
index f49ce8a..f64b4de 100644
--- a/net/d80211/ieee80211_iface.c
+++ b/net/d80211/ieee80211_iface.c
@@ -18,9 +18,22 @@ #include "sta_info.h"
void ieee80211_if_sdata_init(struct ieee80211_sub_if_data *sdata)
{
+ int i;
+
/* Default values for sub-interface parameters */
sdata->drop_unencrypted = 0;
sdata->eapol = 1;
+ for (i = 0; i < IEEE80211_FRAGMENT_MAX; i++)
+ skb_queue_head_init(&sdata->fragments[i].skb_list);
+}
+
+static void ieee80211_if_sdata_deinit(struct ieee80211_sub_if_data *sdata)
+{
+ int i;
+
+ for (i = 0; i < IEEE80211_FRAGMENT_MAX; i++) {
+ __skb_queue_purge(&sdata->fragments[i].skb_list);
+ }
}
/* Must be called with rtnl lock held. */
@@ -212,6 +225,7 @@ void ieee80211_if_reinit(struct net_devi
int i;
ASSERT_RTNL();
+ ieee80211_if_sdata_deinit(sdata);
for (i = 0; i < NUM_DEFAULT_KEYS; i++) {
if (!sdata->keys[i])
continue;
@@ -337,13 +351,10 @@ void ieee80211_if_free(struct net_device
{
struct ieee80211_local *local = dev->ieee80211_ptr;
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
- int i;
/* local->apdev must be NULL when freeing management interface */
BUG_ON(dev == local->apdev);
- for (i = 0; i < IEEE80211_FRAGMENT_MAX; i++)
- if (sdata->fragments[i].skb)
- dev_kfree_skb(sdata->fragments[i].skb);
+ ieee80211_if_sdata_deinit(sdata);
free_netdev(dev);
}
--
1.3.0
next prev parent reply other threads:[~2006-07-18 15:43 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-07-18 15:45 [PATCH 0/9] d80211: pull request Jiri Benc
2006-07-18 15:45 ` [PATCH 1/9] d80211: do not receive through master interface when not scanning Jiri Benc
2006-07-18 15:45 ` [PATCH 2/9] d80211: host_gen_beacon_template flag Jiri Benc
2006-07-18 15:45 ` [PATCH 3/9] d80211: better deallocation of mdev Jiri Benc
2006-07-19 3:07 ` Simon Barber
2006-07-19 10:15 ` Jiri Benc
2006-07-18 15:45 ` [PATCH 4/9] d80211: fix receiving through virtual interfaces Jiri Benc
2006-07-18 15:45 ` [PATCH 5/9] d80211: fix defragmentation Jiri Benc
2006-07-18 15:45 ` Jiri Benc [this message]
2006-07-18 15:45 ` [PATCH 7/9] d80211: SET_NETDEV_DEV for non-master devices Jiri Benc
2006-07-18 15:45 ` [PATCH 8/9] d80211: Replace rc4 code with crypto api arc4 Jiri Benc
2006-07-18 15:45 ` [PATCH 9/9] d80211: Add sparse bitwise annotations Jiri Benc
2006-07-18 15:46 ` [PATCH 0/9] d80211: pull request Jiri Benc
2006-07-28 14:25 ` Jiri Benc
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20060718154527.11F28483BB@silver.suse.cz \
--to=jbenc@suse.cz \
--cc=netdev@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).