From 946651cba26779864bcdbd7e12502f5a36c2de37 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Sat, 15 Feb 2014 00:05:52 +0100 Subject: wl1251: split wl251 platform data to a separate structure Move the wl1251 part of the wl12xx platform data structure into a new structure specifically for wl1251. Change the platform data built-in block and board files accordingly. Signed-off-by: Luciano Coelho Acked-by: Tony Lindgren Reviewed-by: Felipe Balbi Reviewed-by: Sebastian Reichel Reviewed-by: Pavel Machek Signed-off-by: John W. Linville --- arch/arm/mach-omap2/board-omap3pandora.c | 4 ++-- arch/arm/mach-omap2/board-rx51-peripherals.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c index de1bc6bbe585..24f3c1be69a5 100644 --- a/arch/arm/mach-omap2/board-omap3pandora.c +++ b/arch/arm/mach-omap2/board-omap3pandora.c @@ -536,7 +536,7 @@ static struct spi_board_info omap3pandora_spi_board_info[] __initdata = { static void __init pandora_wl1251_init(void) { - struct wl12xx_platform_data pandora_wl1251_pdata; + struct wl1251_platform_data pandora_wl1251_pdata; int ret; memset(&pandora_wl1251_pdata, 0, sizeof(pandora_wl1251_pdata)); @@ -550,7 +550,7 @@ static void __init pandora_wl1251_init(void) goto fail_irq; pandora_wl1251_pdata.use_eeprom = true; - ret = wl12xx_set_platform_data(&pandora_wl1251_pdata); + ret = wl1251_set_platform_data(&pandora_wl1251_pdata); if (ret < 0) goto fail_irq; diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c index 8760bbe3baab..e05e740a4426 100644 --- a/arch/arm/mach-omap2/board-rx51-peripherals.c +++ b/arch/arm/mach-omap2/board-rx51-peripherals.c @@ -84,7 +84,7 @@ enum { RX51_SPI_MIPID, /* LCD panel */ }; -static struct wl12xx_platform_data wl1251_pdata; +static struct wl1251_platform_data wl1251_pdata; static struct tsc2005_platform_data tsc2005_pdata; #if defined(CONFIG_SENSORS_LIS3_I2C) || defined(CONFIG_SENSORS_LIS3_I2C_MODULE) -- cgit v1.2.3 From 1d207cd30b65fdd60d952cb9e100b6f776564f06 Mon Sep 17 00:00:00 2001 From: Sebastian Reichel Date: Sat, 15 Feb 2014 00:05:53 +0100 Subject: wl1251: move power GPIO handling into the driver Move the power GPIO handling from the board code into the driver. This is a dependency for device tree support. Signed-off-by: Sebastian Reichel Reviewed-by: Pavel Machek Acked-by: Tony Lindgren Signed-off-by: John W. Linville --- arch/arm/mach-omap2/board-omap3pandora.c | 2 ++ arch/arm/mach-omap2/board-rx51-peripherals.c | 11 ++-------- drivers/net/wireless/ti/wl1251/sdio.c | 21 +++++++++++++----- drivers/net/wireless/ti/wl1251/spi.c | 33 ++++++++++++++++++---------- drivers/net/wireless/ti/wl1251/wl1251.h | 2 +- include/linux/wl12xx.h | 2 +- 6 files changed, 43 insertions(+), 28 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c index 24f3c1be69a5..cf18340eb3bb 100644 --- a/arch/arm/mach-omap2/board-omap3pandora.c +++ b/arch/arm/mach-omap2/board-omap3pandora.c @@ -541,6 +541,8 @@ static void __init pandora_wl1251_init(void) memset(&pandora_wl1251_pdata, 0, sizeof(pandora_wl1251_pdata)); + pandora_wl1251_pdata.power_gpio = -1; + ret = gpio_request_one(PANDORA_WIFI_IRQ_GPIO, GPIOF_IN, "wl1251 irq"); if (ret < 0) goto fail; diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c index e05e740a4426..ddfc8df83c6a 100644 --- a/arch/arm/mach-omap2/board-rx51-peripherals.c +++ b/arch/arm/mach-omap2/board-rx51-peripherals.c @@ -1173,13 +1173,7 @@ static inline void board_smc91x_init(void) #endif -static void rx51_wl1251_set_power(bool enable) -{ - gpio_set_value(RX51_WL1251_POWER_GPIO, enable); -} - static struct gpio rx51_wl1251_gpios[] __initdata = { - { RX51_WL1251_POWER_GPIO, GPIOF_OUT_INIT_LOW, "wl1251 power" }, { RX51_WL1251_IRQ_GPIO, GPIOF_IN, "wl1251 irq" }, }; @@ -1196,17 +1190,16 @@ static void __init rx51_init_wl1251(void) if (irq < 0) goto err_irq; - wl1251_pdata.set_power = rx51_wl1251_set_power; + wl1251_pdata.power_gpio = RX51_WL1251_POWER_GPIO; rx51_peripherals_spi_board_info[RX51_SPI_WL1251].irq = irq; return; err_irq: gpio_free(RX51_WL1251_IRQ_GPIO); - gpio_free(RX51_WL1251_POWER_GPIO); error: printk(KERN_ERR "wl1251 board initialisation failed\n"); - wl1251_pdata.set_power = NULL; + wl1251_pdata.power_gpio = -1; /* * Now rx51_peripherals_spi_board_info[1].irq is zero and diff --git a/drivers/net/wireless/ti/wl1251/sdio.c b/drivers/net/wireless/ti/wl1251/sdio.c index b75a37a58313..b661f896e9fe 100644 --- a/drivers/net/wireless/ti/wl1251/sdio.c +++ b/drivers/net/wireless/ti/wl1251/sdio.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "wl1251.h" @@ -182,8 +183,9 @@ static int wl1251_sdio_set_power(struct wl1251 *wl, bool enable) * callback in case it wants to do any additional setup, * for example enabling clock buffer for the module. */ - if (wl->set_power) - wl->set_power(true); + if (gpio_is_valid(wl->power_gpio)) + gpio_set_value(wl->power_gpio, true); + ret = pm_runtime_get_sync(&func->dev); if (ret < 0) { @@ -203,8 +205,8 @@ static int wl1251_sdio_set_power(struct wl1251 *wl, bool enable) if (ret < 0) goto out; - if (wl->set_power) - wl->set_power(false); + if (gpio_is_valid(wl->power_gpio)) + gpio_set_value(wl->power_gpio, false); } out: @@ -256,11 +258,20 @@ static int wl1251_sdio_probe(struct sdio_func *func, wl1251_board_data = wl1251_get_platform_data(); if (!IS_ERR(wl1251_board_data)) { - wl->set_power = wl1251_board_data->set_power; + wl->power_gpio = wl1251_board_data->power_gpio; wl->irq = wl1251_board_data->irq; wl->use_eeprom = wl1251_board_data->use_eeprom; } + if (gpio_is_valid(wl->power_gpio)) { + ret = devm_gpio_request(&func->dev, wl->power_gpio, + "wl1251 power"); + if (ret) { + wl1251_error("Failed to request gpio: %d\n", ret); + goto disable; + } + } + if (wl->irq) { irq_set_status_flags(wl->irq, IRQ_NOAUTOEN); ret = request_irq(wl->irq, wl1251_line_irq, 0, "wl1251", wl); diff --git a/drivers/net/wireless/ti/wl1251/spi.c b/drivers/net/wireless/ti/wl1251/spi.c index 62403a147592..6abcbc3f7fc7 100644 --- a/drivers/net/wireless/ti/wl1251/spi.c +++ b/drivers/net/wireless/ti/wl1251/spi.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "wl1251.h" #include "reg.h" @@ -221,8 +222,8 @@ static void wl1251_spi_disable_irq(struct wl1251 *wl) static int wl1251_spi_set_power(struct wl1251 *wl, bool enable) { - if (wl->set_power) - wl->set_power(enable); + if (gpio_is_valid(wl->power_gpio)) + gpio_set_value(wl->power_gpio, enable); return 0; } @@ -271,22 +272,33 @@ static int wl1251_spi_probe(struct spi_device *spi) goto out_free; } - wl->set_power = pdata->set_power; - if (!wl->set_power) { - wl1251_error("set power function missing in platform data"); - return -ENODEV; + wl->power_gpio = pdata->power_gpio; + + if (gpio_is_valid(wl->power_gpio)) { + ret = devm_gpio_request_one(&spi->dev, wl->power_gpio, + GPIOF_OUT_INIT_LOW, "wl1251 power"); + if (ret) { + wl1251_error("Failed to request gpio: %d\n", ret); + goto out_free; + } + } else { + wl1251_error("set power gpio missing in platform data"); + ret = -ENODEV; + goto out_free; } wl->irq = spi->irq; if (wl->irq < 0) { wl1251_error("irq missing in platform data"); - return -ENODEV; + ret = -ENODEV; + goto out_free; } wl->use_eeprom = pdata->use_eeprom; irq_set_status_flags(wl->irq, IRQ_NOAUTOEN); - ret = request_irq(wl->irq, wl1251_irq, 0, DRIVER_NAME, wl); + ret = devm_request_irq(&spi->dev, wl->irq, wl1251_irq, 0, + DRIVER_NAME, wl); if (ret < 0) { wl1251_error("request_irq() failed: %d", ret); goto out_free; @@ -296,13 +308,10 @@ static int wl1251_spi_probe(struct spi_device *spi) ret = wl1251_init_ieee80211(wl); if (ret) - goto out_irq; + goto out_free; return 0; - out_irq: - free_irq(wl->irq, wl); - out_free: ieee80211_free_hw(hw); diff --git a/drivers/net/wireless/ti/wl1251/wl1251.h b/drivers/net/wireless/ti/wl1251/wl1251.h index 235617a7716d..389fe25af1b6 100644 --- a/drivers/net/wireless/ti/wl1251/wl1251.h +++ b/drivers/net/wireless/ti/wl1251/wl1251.h @@ -276,7 +276,7 @@ struct wl1251 { void *if_priv; const struct wl1251_if_operations *if_ops; - void (*set_power)(bool enable); + int power_gpio; int irq; bool use_eeprom; diff --git a/include/linux/wl12xx.h b/include/linux/wl12xx.h index b516b4fa22de..a9c723be1acf 100644 --- a/include/linux/wl12xx.h +++ b/include/linux/wl12xx.h @@ -49,7 +49,7 @@ enum { }; struct wl1251_platform_data { - void (*set_power)(bool enable); + int power_gpio; /* SDIO only: IRQ number if WLAN_IRQ line is used, 0 for SDIO IRQs */ int irq; bool use_eeprom; -- cgit v1.2.3 From fabfb91d50d65b5cb8835a231d7e2a0e7de6e539 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Sat, 15 Mar 2014 15:27:14 -0700 Subject: uml/net_kern: Call dev_consume_skb_any instead of dev_kfree_skb. Replace dev_kfree_skb with dev_consume_skb_any in uml_net_start_xmit as it can be called in hard irq and other contexts. dev_consume_skb_any is used as uml_net_start_xmit typically consumes (not drops) packets. Signed-off-by: "Eric W. Biederman" --- arch/um/drivers/net_kern.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c index 39f186252e02..7d26d9c0b2fb 100644 --- a/arch/um/drivers/net_kern.c +++ b/arch/um/drivers/net_kern.c @@ -240,7 +240,7 @@ static int uml_net_start_xmit(struct sk_buff *skb, struct net_device *dev) spin_unlock_irqrestore(&lp->lock, flags); - dev_kfree_skb(skb); + dev_consume_skb_any(skb); return NETDEV_TX_OK; } -- cgit v1.2.3 From 61b905da33ae25edb6b9d2a5de21e34c3a77efe3 Mon Sep 17 00:00:00 2001 From: Tom Herbert Date: Mon, 24 Mar 2014 15:34:47 -0700 Subject: net: Rename skb->rxhash to skb->hash The packet hash can be considered a property of the packet, not just on RX path. This patch changes name of rxhash and l4_rxhash skbuff fields to be hash and l4_hash respectively. This includes changing uses of the field in the code which don't call the access functions. Signed-off-by: Tom Herbert Signed-off-by: Eric Dumazet Cc: Mahesh Bandewar Signed-off-by: David S. Miller --- arch/arm/net/bpf_jit_32.c | 4 ++-- arch/powerpc/net/bpf_jit_comp.c | 4 ++-- arch/s390/net/bpf_jit_comp.c | 8 ++++---- arch/sparc/net/bpf_jit_comp.c | 2 +- arch/x86/net/bpf_jit_comp.c | 8 ++++---- include/linux/skbuff.h | 28 ++++++++++++++-------------- include/net/sock.h | 4 ++-- include/trace/events/net.h | 12 ++++++------ net/core/dev.c | 13 +++++++------ net/core/filter.c | 2 +- net/core/flow_dissector.c | 10 +++++----- net/packet/af_packet.c | 3 +-- 12 files changed, 49 insertions(+), 49 deletions(-) (limited to 'arch') diff --git a/arch/arm/net/bpf_jit_32.c b/arch/arm/net/bpf_jit_32.c index 271b5e971568..7ddb9c83cdfc 100644 --- a/arch/arm/net/bpf_jit_32.c +++ b/arch/arm/net/bpf_jit_32.c @@ -825,8 +825,8 @@ b_epilogue: break; case BPF_S_ANC_RXHASH: ctx->seen |= SEEN_SKB; - BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, rxhash) != 4); - off = offsetof(struct sk_buff, rxhash); + BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, hash) != 4); + off = offsetof(struct sk_buff, hash); emit(ARM_LDR_I(r_A, r_skb, off), ctx); break; case BPF_S_ANC_VLAN_TAG: diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c index 555034f8505e..4afad6c17d50 100644 --- a/arch/powerpc/net/bpf_jit_comp.c +++ b/arch/powerpc/net/bpf_jit_comp.c @@ -390,9 +390,9 @@ static int bpf_jit_build_body(struct sk_filter *fp, u32 *image, mark)); break; case BPF_S_ANC_RXHASH: - BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, rxhash) != 4); + BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, hash) != 4); PPC_LWZ_OFFS(r_A, r_skb, offsetof(struct sk_buff, - rxhash)); + hash)); break; case BPF_S_ANC_VLAN_TAG: case BPF_S_ANC_VLAN_TAG_PRESENT: diff --git a/arch/s390/net/bpf_jit_comp.c b/arch/s390/net/bpf_jit_comp.c index 708d60e40066..153f8f2cfd56 100644 --- a/arch/s390/net/bpf_jit_comp.c +++ b/arch/s390/net/bpf_jit_comp.c @@ -737,10 +737,10 @@ call_fn: /* lg %r1,(%r13) */ /* icm %r5,3,(%r1) */ EMIT4_DISP(0xbf531000, offsetof(struct net_device, type)); break; - case BPF_S_ANC_RXHASH: /* A = skb->rxhash */ - BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, rxhash) != 4); - /* l %r5,(%r2) */ - EMIT4_DISP(0x58502000, offsetof(struct sk_buff, rxhash)); + case BPF_S_ANC_RXHASH: /* A = skb->hash */ + BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, hash) != 4); + /* l %r5,(%r2) */ + EMIT4_DISP(0x58502000, offsetof(struct sk_buff, hash)); break; case BPF_S_ANC_VLAN_TAG: case BPF_S_ANC_VLAN_TAG_PRESENT: diff --git a/arch/sparc/net/bpf_jit_comp.c b/arch/sparc/net/bpf_jit_comp.c index 01fe9946d388..d96d2a7c78ee 100644 --- a/arch/sparc/net/bpf_jit_comp.c +++ b/arch/sparc/net/bpf_jit_comp.c @@ -618,7 +618,7 @@ void bpf_jit_compile(struct sk_filter *fp) emit_load16(r_A, struct net_device, type, r_A); break; case BPF_S_ANC_RXHASH: - emit_skb_load32(rxhash, r_A); + emit_skb_load32(hash, r_A); break; case BPF_S_ANC_VLAN_TAG: case BPF_S_ANC_VLAN_TAG_PRESENT: diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c index 4ed75dd81d05..293c57b74edc 100644 --- a/arch/x86/net/bpf_jit_comp.c +++ b/arch/x86/net/bpf_jit_comp.c @@ -553,13 +553,13 @@ void bpf_jit_compile(struct sk_filter *fp) } break; case BPF_S_ANC_RXHASH: - BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, rxhash) != 4); - if (is_imm8(offsetof(struct sk_buff, rxhash))) { + BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, hash) != 4); + if (is_imm8(offsetof(struct sk_buff, hash))) { /* mov off8(%rdi),%eax */ - EMIT3(0x8b, 0x47, offsetof(struct sk_buff, rxhash)); + EMIT3(0x8b, 0x47, offsetof(struct sk_buff, hash)); } else { EMIT2(0x8b, 0x87); - EMIT(offsetof(struct sk_buff, rxhash), 4); + EMIT(offsetof(struct sk_buff, hash), 4); } break; case BPF_S_ANC_QUEUE: diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 03db95ab8a8c..aa2c22cb8158 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -444,11 +444,11 @@ static inline u32 skb_mstamp_us_delta(const struct skb_mstamp *t1, * @skb_iif: ifindex of device we arrived on * @tc_index: Traffic control index * @tc_verd: traffic control verdict - * @rxhash: the packet hash computed on receive + * @hash: the packet hash * @queue_mapping: Queue mapping for multiqueue devices * @ndisc_nodetype: router type (from link layer) * @ooo_okay: allow the mapping of a socket to a queue to be changed - * @l4_rxhash: indicate rxhash is a canonical 4-tuple hash over transport + * @l4_hash: indicate hash is a canonical 4-tuple hash over transport * ports. * @wifi_acked_valid: wifi_acked was set * @wifi_acked: whether frame was acked on wifi or not @@ -537,7 +537,7 @@ struct sk_buff { int skb_iif; - __u32 rxhash; + __u32 hash; __be16 vlan_proto; __u16 vlan_tci; @@ -556,7 +556,7 @@ struct sk_buff { #endif __u8 pfmemalloc:1; __u8 ooo_okay:1; - __u8 l4_rxhash:1; + __u8 l4_hash:1; __u8 wifi_acked_valid:1; __u8 wifi_acked:1; __u8 no_fcs:1; @@ -815,40 +815,40 @@ enum pkt_hash_types { static inline void skb_set_hash(struct sk_buff *skb, __u32 hash, enum pkt_hash_types type) { - skb->l4_rxhash = (type == PKT_HASH_TYPE_L4); - skb->rxhash = hash; + skb->l4_hash = (type == PKT_HASH_TYPE_L4); + skb->hash = hash; } void __skb_get_hash(struct sk_buff *skb); static inline __u32 skb_get_hash(struct sk_buff *skb) { - if (!skb->l4_rxhash) + if (!skb->l4_hash) __skb_get_hash(skb); - return skb->rxhash; + return skb->hash; } static inline __u32 skb_get_hash_raw(const struct sk_buff *skb) { - return skb->rxhash; + return skb->hash; } static inline void skb_clear_hash(struct sk_buff *skb) { - skb->rxhash = 0; - skb->l4_rxhash = 0; + skb->hash = 0; + skb->l4_hash = 0; } static inline void skb_clear_hash_if_not_l4(struct sk_buff *skb) { - if (!skb->l4_rxhash) + if (!skb->l4_hash) skb_clear_hash(skb); } static inline void skb_copy_hash(struct sk_buff *to, const struct sk_buff *from) { - to->rxhash = from->rxhash; - to->l4_rxhash = from->l4_rxhash; + to->hash = from->hash; + to->l4_hash = from->l4_hash; }; #ifdef NET_SKBUFF_DATA_USES_OFFSET diff --git a/include/net/sock.h b/include/net/sock.h index 625e65b12366..8d7c431a0660 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -862,9 +862,9 @@ static inline void sock_rps_save_rxhash(struct sock *sk, const struct sk_buff *skb) { #ifdef CONFIG_RPS - if (unlikely(sk->sk_rxhash != skb->rxhash)) { + if (unlikely(sk->sk_rxhash != skb->hash)) { sock_rps_reset_flow(sk); - sk->sk_rxhash = skb->rxhash; + sk->sk_rxhash = skb->hash; } #endif } diff --git a/include/trace/events/net.h b/include/trace/events/net.h index a34f27b2e394..1de256b35807 100644 --- a/include/trace/events/net.h +++ b/include/trace/events/net.h @@ -153,8 +153,8 @@ DECLARE_EVENT_CLASS(net_dev_rx_verbose_template, __field( u16, vlan_tci ) __field( u16, protocol ) __field( u8, ip_summed ) - __field( u32, rxhash ) - __field( bool, l4_rxhash ) + __field( u32, hash ) + __field( bool, l4_hash ) __field( unsigned int, len ) __field( unsigned int, data_len ) __field( unsigned int, truesize ) @@ -179,8 +179,8 @@ DECLARE_EVENT_CLASS(net_dev_rx_verbose_template, __entry->vlan_tci = vlan_tx_tag_get(skb); __entry->protocol = ntohs(skb->protocol); __entry->ip_summed = skb->ip_summed; - __entry->rxhash = skb->rxhash; - __entry->l4_rxhash = skb->l4_rxhash; + __entry->hash = skb->hash; + __entry->l4_hash = skb->l4_hash; __entry->len = skb->len; __entry->data_len = skb->data_len; __entry->truesize = skb->truesize; @@ -191,11 +191,11 @@ DECLARE_EVENT_CLASS(net_dev_rx_verbose_template, __entry->gso_type = skb_shinfo(skb)->gso_type; ), - TP_printk("dev=%s napi_id=%#x queue_mapping=%u skbaddr=%p vlan_tagged=%d vlan_proto=0x%04x vlan_tci=0x%04x protocol=0x%04x ip_summed=%d rxhash=0x%08x l4_rxhash=%d len=%u data_len=%u truesize=%u mac_header_valid=%d mac_header=%d nr_frags=%d gso_size=%d gso_type=%#x", + TP_printk("dev=%s napi_id=%#x queue_mapping=%u skbaddr=%p vlan_tagged=%d vlan_proto=0x%04x vlan_tci=0x%04x protocol=0x%04x ip_summed=%d hash=0x%08x l4_hash=%d len=%u data_len=%u truesize=%u mac_header_valid=%d mac_header=%d nr_frags=%d gso_size=%d gso_type=%#x", __get_str(name), __entry->napi_id, __entry->queue_mapping, __entry->skbaddr, __entry->vlan_tagged, __entry->vlan_proto, __entry->vlan_tci, __entry->protocol, __entry->ip_summed, - __entry->rxhash, __entry->l4_rxhash, __entry->len, + __entry->hash, __entry->l4_hash, __entry->len, __entry->data_len, __entry->truesize, __entry->mac_header_valid, __entry->mac_header, __entry->nr_frags, __entry->gso_size, __entry->gso_type) diff --git a/net/core/dev.c b/net/core/dev.c index 55f8e64c03a2..48dd323d5918 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -2952,7 +2952,7 @@ set_rps_cpu(struct net_device *dev, struct sk_buff *skb, flow_table = rcu_dereference(rxqueue->rps_flow_table); if (!flow_table) goto out; - flow_id = skb->rxhash & flow_table->mask; + flow_id = skb_get_hash(skb) & flow_table->mask; rc = dev->netdev_ops->ndo_rx_flow_steer(dev, skb, rxq_index, flow_id); if (rc < 0) @@ -2986,6 +2986,7 @@ static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb, struct rps_sock_flow_table *sock_flow_table; int cpu = -1; u16 tcpu; + u32 hash; if (skb_rx_queue_recorded(skb)) { u16 index = skb_get_rx_queue(skb); @@ -3014,7 +3015,8 @@ static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb, } skb_reset_network_header(skb); - if (!skb_get_hash(skb)) + hash = skb_get_hash(skb); + if (!hash) goto done; flow_table = rcu_dereference(rxqueue->rps_flow_table); @@ -3023,11 +3025,10 @@ static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb, u16 next_cpu; struct rps_dev_flow *rflow; - rflow = &flow_table->flows[skb->rxhash & flow_table->mask]; + rflow = &flow_table->flows[hash & flow_table->mask]; tcpu = rflow->cpu; - next_cpu = sock_flow_table->ents[skb->rxhash & - sock_flow_table->mask]; + next_cpu = sock_flow_table->ents[hash & sock_flow_table->mask]; /* * If the desired CPU (where last recvmsg was done) is @@ -3056,7 +3057,7 @@ static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb, } if (map) { - tcpu = map->cpus[((u64) skb->rxhash * map->len) >> 32]; + tcpu = map->cpus[((u64) hash * map->len) >> 32]; if (cpu_online(tcpu)) { cpu = tcpu; diff --git a/net/core/filter.c b/net/core/filter.c index ad30d626a5bd..65b75966e206 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -336,7 +336,7 @@ load_b: A = skb->dev->type; continue; case BPF_S_ANC_RXHASH: - A = skb->rxhash; + A = skb->hash; continue; case BPF_S_ANC_CPU: A = raw_smp_processor_id(); diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c index 80201bf69d59..107ed12a5323 100644 --- a/net/core/flow_dissector.c +++ b/net/core/flow_dissector.c @@ -203,8 +203,8 @@ static __always_inline u32 __flow_hash_1word(u32 a) /* * __skb_get_hash: calculate a flow hash based on src/dst addresses - * and src/dst port numbers. Sets rxhash in skb to non-zero hash value - * on success, zero indicates no valid hash. Also, sets l4_rxhash in skb + * and src/dst port numbers. Sets hash in skb to non-zero hash value + * on success, zero indicates no valid hash. Also, sets l4_hash in skb * if hash is a canonical 4-tuple hash over transport ports. */ void __skb_get_hash(struct sk_buff *skb) @@ -216,7 +216,7 @@ void __skb_get_hash(struct sk_buff *skb) return; if (keys.ports) - skb->l4_rxhash = 1; + skb->l4_hash = 1; /* get a consistent hash (same value on both flow directions) */ if (((__force u32)keys.dst < (__force u32)keys.src) || @@ -232,7 +232,7 @@ void __skb_get_hash(struct sk_buff *skb) if (!hash) hash = 1; - skb->rxhash = hash; + skb->hash = hash; } EXPORT_SYMBOL(__skb_get_hash); @@ -344,7 +344,7 @@ static inline int get_xps_queue(struct net_device *dev, struct sk_buff *skb) hash = skb->sk->sk_hash; else hash = (__force u16) skb->protocol ^ - skb->rxhash; + skb->hash; hash = __flow_hash_1word(hash); queue_index = map->queues[ ((u64)hash * map->len) >> 32]; diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 292304404fda..097a354ec8cd 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -1277,7 +1277,7 @@ static unsigned int fanout_demux_hash(struct packet_fanout *f, struct sk_buff *skb, unsigned int num) { - return reciprocal_scale(skb->rxhash, num); + return reciprocal_scale(skb_get_hash(skb), num); } static unsigned int fanout_demux_lb(struct packet_fanout *f, @@ -1362,7 +1362,6 @@ static int packet_rcv_fanout(struct sk_buff *skb, struct net_device *dev, if (!skb) return 0; } - skb_get_hash(skb); idx = fanout_demux_hash(f, skb, num); break; case PACKET_FANOUT_LB: -- cgit v1.2.3 From f8bbbfc3b97f4c7a6c7c23185e520b22bfc3a21d Mon Sep 17 00:00:00 2001 From: Daniel Borkmann Date: Fri, 28 Mar 2014 18:58:18 +0100 Subject: net: filter: add jited flag to indicate jit compiled filters This patch adds a jited flag into sk_filter struct in order to indicate whether a filter is currently jited or not. The size of sk_filter is not being expanded as the 32 bit 'len' member allows upper bits to be reused since a filter can currently only grow as large as BPF_MAXINSNS. Therefore, there's enough room also for other in future needed flags to reuse 'len' field if necessary. The jited flag also allows for having alternative interpreter functions running as currently, we can only detect jit compiled filters by testing fp->bpf_func to not equal the address of sk_run_filter(). Joint work with Alexei Starovoitov. Signed-off-by: Alexei Starovoitov Signed-off-by: Daniel Borkmann Cc: Pablo Neira Ayuso Signed-off-by: David S. Miller --- arch/arm/net/bpf_jit_32.c | 3 ++- arch/powerpc/net/bpf_jit_comp.c | 3 ++- arch/s390/net/bpf_jit_comp.c | 5 ++++- arch/sparc/net/bpf_jit_comp.c | 3 ++- arch/x86/net/bpf_jit_comp.c | 3 ++- include/linux/filter.h | 3 ++- net/core/filter.c | 1 + 7 files changed, 15 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/arm/net/bpf_jit_32.c b/arch/arm/net/bpf_jit_32.c index 7ddb9c83cdfc..6f879c319a9d 100644 --- a/arch/arm/net/bpf_jit_32.c +++ b/arch/arm/net/bpf_jit_32.c @@ -925,6 +925,7 @@ void bpf_jit_compile(struct sk_filter *fp) bpf_jit_dump(fp->len, alloc_size, 2, ctx.target); fp->bpf_func = (void *)ctx.target; + fp->jited = 1; out: kfree(ctx.offsets); return; @@ -932,7 +933,7 @@ out: void bpf_jit_free(struct sk_filter *fp) { - if (fp->bpf_func != sk_run_filter) + if (fp->jited) module_free(NULL, fp->bpf_func); kfree(fp); } diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c index 4afad6c17d50..808ce1cae21a 100644 --- a/arch/powerpc/net/bpf_jit_comp.c +++ b/arch/powerpc/net/bpf_jit_comp.c @@ -689,6 +689,7 @@ void bpf_jit_compile(struct sk_filter *fp) ((u64 *)image)[0] = (u64)code_base; ((u64 *)image)[1] = local_paca->kernel_toc; fp->bpf_func = (void *)image; + fp->jited = 1; } out: kfree(addrs); @@ -697,7 +698,7 @@ out: void bpf_jit_free(struct sk_filter *fp) { - if (fp->bpf_func != sk_run_filter) + if (fp->jited) module_free(NULL, fp->bpf_func); kfree(fp); } diff --git a/arch/s390/net/bpf_jit_comp.c b/arch/s390/net/bpf_jit_comp.c index 153f8f2cfd56..9c36dc398f90 100644 --- a/arch/s390/net/bpf_jit_comp.c +++ b/arch/s390/net/bpf_jit_comp.c @@ -877,6 +877,7 @@ void bpf_jit_compile(struct sk_filter *fp) if (jit.start) { set_memory_ro((unsigned long)header, header->pages); fp->bpf_func = (void *) jit.start; + fp->jited = 1; } out: kfree(addrs); @@ -887,10 +888,12 @@ void bpf_jit_free(struct sk_filter *fp) unsigned long addr = (unsigned long)fp->bpf_func & PAGE_MASK; struct bpf_binary_header *header = (void *)addr; - if (fp->bpf_func == sk_run_filter) + if (!fp->jited) goto free_filter; + set_memory_rw(addr, header->pages); module_free(NULL, header); + free_filter: kfree(fp); } diff --git a/arch/sparc/net/bpf_jit_comp.c b/arch/sparc/net/bpf_jit_comp.c index d96d2a7c78ee..a82c6b2a9780 100644 --- a/arch/sparc/net/bpf_jit_comp.c +++ b/arch/sparc/net/bpf_jit_comp.c @@ -809,6 +809,7 @@ cond_branch: f_offset = addrs[i + filter[i].jf]; if (image) { bpf_flush_icache(image, image + proglen); fp->bpf_func = (void *)image; + fp->jited = 1; } out: kfree(addrs); @@ -817,7 +818,7 @@ out: void bpf_jit_free(struct sk_filter *fp) { - if (fp->bpf_func != sk_run_filter) + if (fp->jited) module_free(NULL, fp->bpf_func); kfree(fp); } diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c index 293c57b74edc..dc017735bb91 100644 --- a/arch/x86/net/bpf_jit_comp.c +++ b/arch/x86/net/bpf_jit_comp.c @@ -772,6 +772,7 @@ cond_branch: f_offset = addrs[i + filter[i].jf] - addrs[i]; bpf_flush_icache(header, image + proglen); set_memory_ro((unsigned long)header, header->pages); fp->bpf_func = (void *)image; + fp->jited = 1; } out: kfree(addrs); @@ -791,7 +792,7 @@ static void bpf_jit_free_deferred(struct work_struct *work) void bpf_jit_free(struct sk_filter *fp) { - if (fp->bpf_func != sk_run_filter) { + if (fp->jited) { INIT_WORK(&fp->work, bpf_jit_free_deferred); schedule_work(&fp->work); } else { diff --git a/include/linux/filter.h b/include/linux/filter.h index e568c8ef896b..e65e23087367 100644 --- a/include/linux/filter.h +++ b/include/linux/filter.h @@ -25,7 +25,8 @@ struct sock; struct sk_filter { atomic_t refcnt; - unsigned int len; /* Number of filter blocks */ + u32 jited:1, /* Is our filter JIT'ed? */ + len:31; /* Number of filter blocks */ struct rcu_head rcu; unsigned int (*bpf_func)(const struct sk_buff *skb, const struct sock_filter *filter); diff --git a/net/core/filter.c b/net/core/filter.c index 65b75966e206..bb3c76458ca9 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -646,6 +646,7 @@ static int __sk_prepare_filter(struct sk_filter *fp) int err; fp->bpf_func = sk_run_filter; + fp->jited = 0; err = sk_chk_filter(fp->insns, fp->len); if (err) -- cgit v1.2.3