diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2008-06-30 09:10:45 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-07-02 15:48:33 -0400 |
commit | 49461622edf74cd1e1a1056cee3ca8dd90cd9556 (patch) | |
tree | 201add958aa18af22b88b6ddfb93df841213b1fb /net/mac80211/rx.c | |
parent | d9e8a70fa20dc3eaa00859a6eac0adfaef910c77 (diff) |
mac80211: get rid of function pointers in RX path
This changes the RX path to no longer use function pointers for
RX handlers but rather invoke them directly. If debugging is
enabled, mark the RX handlers noinline because otherwise they
all get inlined into ieee80211_invoke_rx_handlers() which makes
it harder to see where a bug is.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/rx.c')
-rw-r--r-- | net/mac80211/rx.c | 97 |
1 files changed, 44 insertions, 53 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 8962d1355f04..289112777e90 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -386,7 +386,7 @@ static void ieee80211_verify_ip_alignment(struct ieee80211_rx_data *rx) | |||
386 | 386 | ||
387 | /* rx handlers */ | 387 | /* rx handlers */ |
388 | 388 | ||
389 | static ieee80211_rx_result | 389 | static ieee80211_rx_result debug_noinline |
390 | ieee80211_rx_h_passive_scan(struct ieee80211_rx_data *rx) | 390 | ieee80211_rx_h_passive_scan(struct ieee80211_rx_data *rx) |
391 | { | 391 | { |
392 | struct ieee80211_local *local = rx->local; | 392 | struct ieee80211_local *local = rx->local; |
@@ -463,7 +463,7 @@ ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx) | |||
463 | } | 463 | } |
464 | 464 | ||
465 | 465 | ||
466 | static ieee80211_rx_result | 466 | static ieee80211_rx_result debug_noinline |
467 | ieee80211_rx_h_check(struct ieee80211_rx_data *rx) | 467 | ieee80211_rx_h_check(struct ieee80211_rx_data *rx) |
468 | { | 468 | { |
469 | struct ieee80211_hdr *hdr; | 469 | struct ieee80211_hdr *hdr; |
@@ -522,7 +522,7 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx) | |||
522 | } | 522 | } |
523 | 523 | ||
524 | 524 | ||
525 | static ieee80211_rx_result | 525 | static ieee80211_rx_result debug_noinline |
526 | ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) | 526 | ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) |
527 | { | 527 | { |
528 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data; | 528 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data; |
@@ -710,7 +710,7 @@ static int ap_sta_ps_end(struct net_device *dev, struct sta_info *sta) | |||
710 | return sent; | 710 | return sent; |
711 | } | 711 | } |
712 | 712 | ||
713 | static ieee80211_rx_result | 713 | static ieee80211_rx_result debug_noinline |
714 | ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) | 714 | ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) |
715 | { | 715 | { |
716 | struct sta_info *sta = rx->sta; | 716 | struct sta_info *sta = rx->sta; |
@@ -858,7 +858,7 @@ ieee80211_reassemble_find(struct ieee80211_sub_if_data *sdata, | |||
858 | return NULL; | 858 | return NULL; |
859 | } | 859 | } |
860 | 860 | ||
861 | static ieee80211_rx_result | 861 | static ieee80211_rx_result debug_noinline |
862 | ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) | 862 | ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) |
863 | { | 863 | { |
864 | struct ieee80211_hdr *hdr; | 864 | struct ieee80211_hdr *hdr; |
@@ -974,7 +974,7 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) | |||
974 | return RX_CONTINUE; | 974 | return RX_CONTINUE; |
975 | } | 975 | } |
976 | 976 | ||
977 | static ieee80211_rx_result | 977 | static ieee80211_rx_result debug_noinline |
978 | ieee80211_rx_h_ps_poll(struct ieee80211_rx_data *rx) | 978 | ieee80211_rx_h_ps_poll(struct ieee80211_rx_data *rx) |
979 | { | 979 | { |
980 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(rx->dev); | 980 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(rx->dev); |
@@ -1049,7 +1049,7 @@ ieee80211_rx_h_ps_poll(struct ieee80211_rx_data *rx) | |||
1049 | return RX_QUEUED; | 1049 | return RX_QUEUED; |
1050 | } | 1050 | } |
1051 | 1051 | ||
1052 | static ieee80211_rx_result | 1052 | static ieee80211_rx_result debug_noinline |
1053 | ieee80211_rx_h_remove_qos_control(struct ieee80211_rx_data *rx) | 1053 | ieee80211_rx_h_remove_qos_control(struct ieee80211_rx_data *rx) |
1054 | { | 1054 | { |
1055 | u16 fc = rx->fc; | 1055 | u16 fc = rx->fc; |
@@ -1367,7 +1367,7 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx) | |||
1367 | } | 1367 | } |
1368 | } | 1368 | } |
1369 | 1369 | ||
1370 | static ieee80211_rx_result | 1370 | static ieee80211_rx_result debug_noinline |
1371 | ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx) | 1371 | ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx) |
1372 | { | 1372 | { |
1373 | struct net_device *dev = rx->dev; | 1373 | struct net_device *dev = rx->dev; |
@@ -1484,7 +1484,7 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx) | |||
1484 | return RX_QUEUED; | 1484 | return RX_QUEUED; |
1485 | } | 1485 | } |
1486 | 1486 | ||
1487 | static ieee80211_rx_result | 1487 | static ieee80211_rx_result debug_noinline |
1488 | ieee80211_rx_h_data(struct ieee80211_rx_data *rx) | 1488 | ieee80211_rx_h_data(struct ieee80211_rx_data *rx) |
1489 | { | 1489 | { |
1490 | struct net_device *dev = rx->dev; | 1490 | struct net_device *dev = rx->dev; |
@@ -1515,7 +1515,7 @@ ieee80211_rx_h_data(struct ieee80211_rx_data *rx) | |||
1515 | return RX_QUEUED; | 1515 | return RX_QUEUED; |
1516 | } | 1516 | } |
1517 | 1517 | ||
1518 | static ieee80211_rx_result | 1518 | static ieee80211_rx_result debug_noinline |
1519 | ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx) | 1519 | ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx) |
1520 | { | 1520 | { |
1521 | struct ieee80211_local *local = rx->local; | 1521 | struct ieee80211_local *local = rx->local; |
@@ -1559,7 +1559,7 @@ ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx) | |||
1559 | return RX_CONTINUE; | 1559 | return RX_CONTINUE; |
1560 | } | 1560 | } |
1561 | 1561 | ||
1562 | static ieee80211_rx_result | 1562 | static ieee80211_rx_result debug_noinline |
1563 | ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx) | 1563 | ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx) |
1564 | { | 1564 | { |
1565 | struct ieee80211_sub_if_data *sdata; | 1565 | struct ieee80211_sub_if_data *sdata; |
@@ -1732,66 +1732,57 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx) | |||
1732 | dev_kfree_skb(skb); | 1732 | dev_kfree_skb(skb); |
1733 | } | 1733 | } |
1734 | 1734 | ||
1735 | typedef ieee80211_rx_result (*ieee80211_rx_handler)(struct ieee80211_rx_data *); | ||
1736 | static ieee80211_rx_handler ieee80211_rx_handlers[] = | ||
1737 | { | ||
1738 | ieee80211_rx_h_passive_scan, | ||
1739 | ieee80211_rx_h_check, | ||
1740 | ieee80211_rx_h_decrypt, | ||
1741 | ieee80211_rx_h_sta_process, | ||
1742 | ieee80211_rx_h_defragment, | ||
1743 | ieee80211_rx_h_ps_poll, | ||
1744 | ieee80211_rx_h_michael_mic_verify, | ||
1745 | /* this must be after decryption - so header is counted in MPDU mic | ||
1746 | * must be before pae and data, so QOS_DATA format frames | ||
1747 | * are not passed to user space by these functions | ||
1748 | */ | ||
1749 | ieee80211_rx_h_remove_qos_control, | ||
1750 | ieee80211_rx_h_amsdu, | ||
1751 | ieee80211_rx_h_data, | ||
1752 | ieee80211_rx_h_ctrl, | ||
1753 | ieee80211_rx_h_mgmt, | ||
1754 | NULL | ||
1755 | }; | ||
1756 | 1735 | ||
1757 | static void ieee80211_invoke_rx_handlers(struct ieee80211_sub_if_data *sdata, | 1736 | static void ieee80211_invoke_rx_handlers(struct ieee80211_sub_if_data *sdata, |
1758 | struct ieee80211_rx_data *rx, | 1737 | struct ieee80211_rx_data *rx, |
1759 | struct sk_buff *skb) | 1738 | struct sk_buff *skb) |
1760 | { | 1739 | { |
1761 | ieee80211_rx_handler *handler; | ||
1762 | ieee80211_rx_result res = RX_DROP_MONITOR; | 1740 | ieee80211_rx_result res = RX_DROP_MONITOR; |
1763 | 1741 | ||
1764 | rx->skb = skb; | 1742 | rx->skb = skb; |
1765 | rx->sdata = sdata; | 1743 | rx->sdata = sdata; |
1766 | rx->dev = sdata->dev; | 1744 | rx->dev = sdata->dev; |
1767 | 1745 | ||
1768 | for (handler = ieee80211_rx_handlers; *handler != NULL; handler++) { | 1746 | #define CALL_RXH(rxh) \ |
1769 | res = (*handler)(rx); | 1747 | res = rxh(rx); \ |
1770 | 1748 | if (res != RX_CONTINUE) \ | |
1771 | switch (res) { | 1749 | goto rxh_done; |
1772 | case RX_CONTINUE: | 1750 | |
1773 | continue; | 1751 | CALL_RXH(ieee80211_rx_h_passive_scan) |
1774 | case RX_DROP_UNUSABLE: | 1752 | CALL_RXH(ieee80211_rx_h_check) |
1775 | case RX_DROP_MONITOR: | 1753 | CALL_RXH(ieee80211_rx_h_decrypt) |
1776 | I802_DEBUG_INC(sdata->local->rx_handlers_drop); | 1754 | CALL_RXH(ieee80211_rx_h_sta_process) |
1777 | if (rx->sta) | 1755 | CALL_RXH(ieee80211_rx_h_defragment) |
1778 | rx->sta->rx_dropped++; | 1756 | CALL_RXH(ieee80211_rx_h_ps_poll) |
1779 | break; | 1757 | CALL_RXH(ieee80211_rx_h_michael_mic_verify) |
1780 | case RX_QUEUED: | 1758 | /* must be after MMIC verify so header is counted in MPDU mic */ |
1781 | I802_DEBUG_INC(sdata->local->rx_handlers_queued); | 1759 | CALL_RXH(ieee80211_rx_h_remove_qos_control) |
1782 | break; | 1760 | CALL_RXH(ieee80211_rx_h_amsdu) |
1783 | } | 1761 | CALL_RXH(ieee80211_rx_h_data) |
1784 | break; | 1762 | CALL_RXH(ieee80211_rx_h_ctrl) |
1785 | } | 1763 | CALL_RXH(ieee80211_rx_h_mgmt) |
1786 | 1764 | ||
1765 | #undef CALL_RXH | ||
1766 | |||
1767 | rxh_done: | ||
1787 | switch (res) { | 1768 | switch (res) { |
1788 | case RX_CONTINUE: | ||
1789 | case RX_DROP_MONITOR: | 1769 | case RX_DROP_MONITOR: |
1770 | I802_DEBUG_INC(sdata->local->rx_handlers_drop); | ||
1771 | if (rx->sta) | ||
1772 | rx->sta->rx_dropped++; | ||
1773 | /* fall through */ | ||
1774 | case RX_CONTINUE: | ||
1790 | ieee80211_rx_cooked_monitor(rx); | 1775 | ieee80211_rx_cooked_monitor(rx); |
1791 | break; | 1776 | break; |
1792 | case RX_DROP_UNUSABLE: | 1777 | case RX_DROP_UNUSABLE: |
1778 | I802_DEBUG_INC(sdata->local->rx_handlers_drop); | ||
1779 | if (rx->sta) | ||
1780 | rx->sta->rx_dropped++; | ||
1793 | dev_kfree_skb(rx->skb); | 1781 | dev_kfree_skb(rx->skb); |
1794 | break; | 1782 | break; |
1783 | case RX_QUEUED: | ||
1784 | I802_DEBUG_INC(sdata->local->rx_handlers_queued); | ||
1785 | break; | ||
1795 | } | 1786 | } |
1796 | } | 1787 | } |
1797 | 1788 | ||