* [PATCH v2] hso: Use static attribute groups for sysfs entry
From: Takashi Iwai @ 2015-02-05 10:15 UTC (permalink / raw)
To: David Miller; +Cc: Jan Dumon, linux-usb, netdev
Pass the static attribute groups and the driver data via
tty_port_register_device_attr() instead of manual device_create_file()
and device_remove_file() calls.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
v1->v2: rebased to linux-next
drivers/net/usb/hso.c | 17 ++++++++++-------
1 file changed, 10 insertions(+), 7 deletions(-)
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c
index 7833bd1d9791..6b8efcabb816 100644
--- a/drivers/net/usb/hso.c
+++ b/drivers/net/usb/hso.c
@@ -531,6 +531,13 @@ static ssize_t hso_sysfs_show_porttype(struct device *dev,
}
static DEVICE_ATTR(hsotype, S_IRUGO, hso_sysfs_show_porttype, NULL);
+static struct attribute *hso_serial_dev_attrs[] = {
+ &dev_attr_hsotype.attr,
+ NULL
+};
+
+ATTRIBUTE_GROUPS(hso_serial_dev);
+
static int hso_urb_to_index(struct hso_serial *serial, struct urb *urb)
{
int idx;
@@ -2236,9 +2243,6 @@ static int hso_stop_serial_device(struct hso_device *hso_dev)
static void hso_serial_tty_unregister(struct hso_serial *serial)
{
- if (serial->parent->dev)
- device_remove_file(serial->parent->dev, &dev_attr_hsotype);
-
tty_unregister_device(tty_drv, serial->minor);
}
@@ -2274,11 +2278,10 @@ static int hso_serial_common_create(struct hso_serial *serial, int num_urbs,
goto exit;
/* register our minor number */
- serial->parent->dev = tty_port_register_device(&serial->port, tty_drv,
- minor, &serial->parent->interface->dev);
+ serial->parent->dev = tty_port_register_device_attr(&serial->port,
+ tty_drv, minor, &serial->parent->interface->dev,
+ serial->parent, hso_serial_dev_groups);
dev = serial->parent->dev;
- dev_set_drvdata(dev, serial->parent);
- i = device_create_file(dev, &dev_attr_hsotype);
/* fill in specific data for later use */
serial->minor = minor;
--
2.2.2
^ permalink raw reply related
* Re: [PATCH 0/6 v2 net-next] rhashtable fixes
From: Thomas Graf @ 2015-02-05 10:19 UTC (permalink / raw)
To: Ying Xue; +Cc: davem, netdev, herbert
In-Reply-To: <54D3346E.4040302@windriver.com>
On 02/05/15 at 05:14pm, Ying Xue wrote:
> On 02/05/2015 04:47 PM, Thomas Graf wrote:
> > On 02/05/15 at 10:32am, Ying Xue wrote:
> >> After I applied the sires, it sounds like panic doesn't occur any more. But soft
> >> lockup still happens although the frequency of its reproduction is much lower
> >> than before. Please take a look at its relevant log:
> >
> > Thanks for testing and the report. I had run your bind_netlink test
> > overnight on a 4 CPU VM. Anything particular that might help trigger it?
Thanks. I will keep trying to reproduce. Can you try the following
patch in the meantime?
diff --git a/lib/rhashtable.c b/lib/rhashtable.c
index 5919d63..1c65be2 100644
--- a/lib/rhashtable.c
+++ b/lib/rhashtable.c
@@ -593,7 +593,7 @@ void rhashtable_insert(struct rhashtable *ht, struct rhash_head *obj)
tbl = rht_dereference_rcu(ht->future_tbl, ht);
old_tbl = rht_dereference_rcu(ht->tbl, ht);
- hash = head_hashfn(ht, tbl, obj);
+ hash = obj_raw_hashfn(ht, rht_obj(ht, obj));
lock_buckets(tbl, old_tbl, hash);
__rhashtable_insert(ht, obj, tbl, hash);
@@ -835,7 +835,7 @@ bool rhashtable_lookup_compare_insert(struct rhashtable *ht,
rcu_read_lock();
old_tbl = rht_dereference_rcu(ht->tbl, ht);
new_tbl = rht_dereference_rcu(ht->future_tbl, ht);
- new_hash = head_hashfn(ht, new_tbl, obj);
+ new_hash = obj_raw_hashfn(ht, rht_obj(ht, obj));
lock_buckets(new_tbl, old_tbl, new_hash);
^ permalink raw reply related
* Re: [PATCH net-next] i40e: mark constant as ULL
From: Stefan Assmann @ 2015-02-05 10:15 UTC (permalink / raw)
To: Jeff Kirsher; +Cc: netdev, davem, e1000-devel
In-Reply-To: <1423072177.2589.66.camel@jtkirshe-mobl>
On 04.02.2015 18:49, Jeff Kirsher wrote:
> On Wed, 2015-02-04 at 12:41 +0100, Stefan Assmann wrote:
>> This avoids a compile error on 32bit.
>>
>> Signed-off-by: Stefan Assmann <sassmann@kpanic.de>
>> ---
>> drivers/net/ethernet/intel/i40e/i40e_lan_hmc.c | 2 +-
>> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> Come to find out, I already have a fix in my queue for this. So I will
> be dropping your patch.
>
> The patch in my queue fixes the issue by doing the folling change:
> - mask = 0xFFFFFFFFFFFFFFFF;
> + mask = ~(u64)0;
>
OK.
Stefan
^ permalink raw reply
* Re: [PATCH net-next] bridge: Let bridge not age 'externally' learnt FDB entries, they are removed when 'external' entity notifies the aging
From: Siva Mannem @ 2015-02-05 10:26 UTC (permalink / raw)
To: David Miller
Cc: Scott Feldman, Roopa Prabhu, Netdev, Jiří Pírko
In-Reply-To: <20150204.235308.71797582017426266.davem@davemloft.net>
On Thu, Feb 5, 2015 at 1:23 PM, David Miller <davem@davemloft.net> wrote:
> From: Scott Feldman <sfeldma@gmail.com>
> Date: Wed, 4 Feb 2015 23:13:07 -0800
>
>> I'd like to see this patch reverted so we can have a more
>> comprehensive discussion/solution. With this patch applied, the only
>> user (rocker) of NETDEV_SWITCH_FDB_ADD is broken. So please undo this
>> patch so rocker isn't broken and let's work on a knob to suit both
>> modes: 1) let bridge manage aging, 2) let device manage aging.
>
> Patch reverted.
I now see why rocker is broken. Sorry for the churn.
As Scott/Roopa suggested, a new flag IFLA_BRPORT_AGING_SYNC (similar
to IFLA_BRPORT_LEARNING_SYNC) can be defined and stored in
net_bridge_port->flags when user configures it. Some thing like below.
$ sudo bridge link set dev swp1 ageing_sync on self
And bridge ageing logic does not age externally learnt entry *only* if
IFLA_BRPORT_AGING_SYNC flag on fdb entry's net_bridge_port is set.
This ensures that existing behavior continues to be default behavior
and is of no harm to rocker.
Please let me know your comments on above approach.
--
Regards,
Siva Mannem.
^ permalink raw reply
* Re: [PATCH net v4] net: ipv6: allow explicitly choosing optimistic addresses
From: Hannes Frederic Sowa @ 2015-02-05 10:51 UTC (permalink / raw)
To: Erik Kline; +Cc: netdev, lorenzo
In-Reply-To: <1423047683-16267-1-git-send-email-ek@google.com>
Hi,
On Mi, 2015-02-04 at 20:01 +0900, Erik Kline wrote:
> RFC 4429 ("Optimistic DAD") states that optimistic addresses
> should be treated as deprecated addresses. From section 2.1:
>
> Unless noted otherwise, components of the IPv6 protocol stack
> should treat addresses in the Optimistic state equivalently to
> those in the Deprecated state, indicating that the address is
> available for use but should not be used if another suitable
> address is available.
>
> Optimistic addresses are indeed avoided when other addresses are
> available (i.e. at source address selection time), but they have
> not heretofore been available for things like explicit bind() and
> sendmsg() with struct in6_pktinfo, etc.
>
> This change makes optimistic addresses treated more like
> deprecated addresses than tentative ones.
>
> Signed-off-by: Erik Kline <ek@google.com>
Acked-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
> ---
> include/net/addrconf.h | 3 +++
> net/ipv6/addrconf.c | 19 +++++++++++++++++--
> net/ipv6/ndisc.c | 4 +++-
> 3 files changed, 23 insertions(+), 3 deletions(-)
>
> diff --git a/include/net/addrconf.h b/include/net/addrconf.h
> index d13573b..80456f7 100644
> --- a/include/net/addrconf.h
> +++ b/include/net/addrconf.h
> @@ -62,6 +62,9 @@ int addrconf_set_dstaddr(struct net *net, void __user *arg);
>
> int ipv6_chk_addr(struct net *net, const struct in6_addr *addr,
> const struct net_device *dev, int strict);
> +int ipv6_chk_addr_and_flags(struct net *net, const struct in6_addr *addr,
> + const struct net_device *dev, int strict,
> + u32 banned_flags);
>
> #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
> int ipv6_chk_home_addr(struct net *net, const struct in6_addr *addr);
> diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
> index f7c8bbe..62900ae 100644
> --- a/net/ipv6/addrconf.c
> +++ b/net/ipv6/addrconf.c
> @@ -1519,15 +1519,30 @@ static int ipv6_count_addresses(struct inet6_dev *idev)
> int ipv6_chk_addr(struct net *net, const struct in6_addr *addr,
> const struct net_device *dev, int strict)
> {
> + return ipv6_chk_addr_and_flags(net, addr, dev, strict, IFA_F_TENTATIVE);
> +}
> +EXPORT_SYMBOL(ipv6_chk_addr);
> +
> +int ipv6_chk_addr_and_flags(struct net *net, const struct in6_addr *addr,
> + const struct net_device *dev, int strict,
> + u32 banned_flags)
> +{
> struct inet6_ifaddr *ifp;
> unsigned int hash = inet6_addr_hash(addr);
> + u32 ifp_flags;
>
> rcu_read_lock_bh();
> hlist_for_each_entry_rcu(ifp, &inet6_addr_lst[hash], addr_lst) {
> if (!net_eq(dev_net(ifp->idev->dev), net))
> continue;
> + /* Decouple optimistic from tentative for evaluation here.
> + * Ban optimistic addresses explicitly, when required.
> + */
> + ifp_flags = (ifp->flags&IFA_F_OPTIMISTIC)
> + ? (ifp->flags&~IFA_F_TENTATIVE)
> + : ifp->flags;
> if (ipv6_addr_equal(&ifp->addr, addr) &&
> - !(ifp->flags&IFA_F_TENTATIVE) &&
> + !(ifp_flags&banned_flags) &&
> (dev == NULL || ifp->idev->dev == dev ||
> !(ifp->scope&(IFA_LINK|IFA_HOST) || strict))) {
> rcu_read_unlock_bh();
> @@ -1538,7 +1553,7 @@ int ipv6_chk_addr(struct net *net, const struct in6_addr *addr,
> rcu_read_unlock_bh();
> return 0;
> }
> -EXPORT_SYMBOL(ipv6_chk_addr);
> +EXPORT_SYMBOL(ipv6_chk_addr_and_flags);
Nit: I don't think the export is necessary.
Bye,
Hannes
^ permalink raw reply
* Re: [PATCH net] pktgen: fix UDP checksum computation
From: Thomas Graf @ 2015-02-05 10:52 UTC (permalink / raw)
To: Sabrina Dubroca; +Cc: davem, netdev
In-Reply-To: <1423087730-9201-1-git-send-email-sd@queasysnail.net>
On 02/04/15 at 11:08pm, Sabrina Dubroca wrote:
> This patch fixes two issues in UDP checksum computation in pktgen.
>
> First, the pseudo-header uses the source and destination IP
> addresses. Currently, the ports are used for IPv4.
>
> Second, the UDP checksum covers both header and data. So we need to
> generate the data earlier (move pktgen_finalize_skb up), and compute
> the checksum for UDP header + data.
>
> Fixes: c26bf4a51308c ("pktgen: Add UDPCSUM flag to support UDP checksums")
> Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
Acked-by: Thomas Graf <tgraf@suug.ch>
Thanks for fixing this.
^ permalink raw reply
* Re: [PATCH net-next v2] hyper-v: allow access to vmbus from userspace driver
From: Vitaly Kuznetsov @ 2015-02-05 11:01 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: dev, devel, Haiyang Zhang, netdev
In-Reply-To: <20150204152029.65f02d64@urahara>
Stephen Hemminger <stephen@networkplumber.org> writes:
> This is enables the hyper-v driver for DPDK <dev@dpdk.org>.
> The hv_uio driver needs to access the shared vmbus monitor
> pages.
Why can't we just make vmbus_connection struct public?
>
> I would also like to put hv_uio in upstream kernel like other
> uio drivers, but need to get API accepted with DPDK first.
>
> Signed-off-by: Stas Egorov <segorov@mirantis.com>
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
>
> ---
> v2 - simplify and rename to vmbus_get_monitor_pages
>
> drivers/hv/connection.c | 20 +++++++++++++++++---
> include/linux/hyperv.h | 3 +++
> 2 files changed, 20 insertions(+), 3 deletions(-)
>
> --- a/drivers/hv/connection.c 2015-02-03 10:58:51.751752450 -0800
> +++ b/drivers/hv/connection.c 2015-02-04 14:59:51.636194383 -0800
> @@ -64,6 +64,15 @@ static __u32 vmbus_get_next_version(__u3
> }
> }
>
> +void vmbus_get_monitor_pages(unsigned long *int_page,
> + unsigned long monitor_pages[2])
> +{
Too weird to be a public interface in my opinion.
> + *int_page = (unsigned long)vmbus_connection.int_page;
> + monitor_pages[0] = (unsigned long)vmbus_connection.monitor_pages[0];
> + monitor_pages[1] = (unsigned long)vmbus_connection.monitor_pages[1];
> +}
> +EXPORT_SYMBOL_GPL(vmbus_get_monitor_pages);
> +
> static int vmbus_negotiate_version(struct vmbus_channel_msginfo *msginfo,
> __u32 version)
> {
> @@ -347,10 +356,7 @@ static void process_chn_event(u32 relid)
> else
> bytes_to_read = 0;
> } while (read_state && (bytes_to_read != 0));
> - } else {
> - pr_err("no channel callback for relid - %u\n", relid);
> }
> -
> }
This change wasn't mentioned in your commit msg.
>
> /*
> --- a/include/linux/hyperv.h 2015-02-03 10:58:51.751752450 -0800
> +++ b/include/linux/hyperv.h 2015-02-04 15:00:26.388355012 -0800
> @@ -868,6 +868,9 @@ extern int vmbus_recvpacket_raw(struct v
>
> extern void vmbus_ontimer(unsigned long data);
>
> +extern void vmbus_get_monitor_pages(unsigned long *int_page,
> + unsigned long monitor_pages[2]);
> +
> /* Base driver object */
> struct hv_driver {
> const char *name;
> _______________________________________________
> devel mailing list
> devel@linuxdriverproject.org
> http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
--
Vitaly
^ permalink raw reply
* Re: [PATCH net-next] bridge: Let bridge not age 'externally' learnt FDB entries, they are removed when 'external' entity notifies the aging
From: B Viswanath @ 2015-02-05 11:05 UTC (permalink / raw)
To: Siva Mannem
Cc: David Miller, Scott Feldman, Roopa Prabhu, Netdev,
Jiří Pírko
In-Reply-To: <CA+CtxLRaJ+p=y1LCgap48vqH3b4VjxKQO55Yy5cyazng4WtxPw@mail.gmail.com>
On 5 February 2015 at 15:56, Siva Mannem <siva.mannem.lnx@gmail.com> wrote:
> On Thu, Feb 5, 2015 at 1:23 PM, David Miller <davem@davemloft.net> wrote:
>> From: Scott Feldman <sfeldma@gmail.com>
>> Date: Wed, 4 Feb 2015 23:13:07 -0800
>>
>>> I'd like to see this patch reverted so we can have a more
>>> comprehensive discussion/solution. With this patch applied, the only
>>> user (rocker) of NETDEV_SWITCH_FDB_ADD is broken. So please undo this
>>> patch so rocker isn't broken and let's work on a knob to suit both
>>> modes: 1) let bridge manage aging, 2) let device manage aging.
>>
>> Patch reverted.
>
> I now see why rocker is broken. Sorry for the churn.
> As Scott/Roopa suggested, a new flag IFLA_BRPORT_AGING_SYNC (similar
> to IFLA_BRPORT_LEARNING_SYNC) can be defined and stored in
> net_bridge_port->flags when user configures it. Some thing like below.
>
> $ sudo bridge link set dev swp1 ageing_sync on self
>
> And bridge ageing logic does not age externally learnt entry *only* if
> IFLA_BRPORT_AGING_SYNC flag on fdb entry's net_bridge_port is set.
> This ensures that existing behavior continues to be default behavior
> and is of no harm to rocker.
>
> Please let me know your comments on above approach.
I am not sure you really want to pass on this burden of deciding who
should age to the end user. I think user should not be forced to be
aware of all the device and driver properties.
May be a different way would be that -
1. driver specifies whether it can supporting ageing by itself (the
chip) during registration.
2. driver also allows that kernel turn off the driver/device ageing.
3. when a bridge is created with all ports from same device which
supports ageing (and which is currently enabled), then bridge defers
ageing to driver. Otherwise bridge disables ageing on all
participating devices and takes care of ageing by itself.
4. When ageing is disabled on a device, all other bridges that use any
ports from that device start ageing themselves.
I guess this sounds complicated, but it can ensure that user gets the
best default behaviour based on the device. Any alternate suggestions
?
Thanks
vissu
> --
> Regards,
> Siva Mannem.
> --
> 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
^ permalink raw reply
* [PATCH] ARCNET: Add missing error check for devm_kzalloc
From: Kiran Padwal @ 2015-02-05 11:31 UTC (permalink / raw)
To: David S. Miller
Cc: Michael Grzeschik, netdev, linux-kernel, Kiran Padwal,
Kiran Padwal
This patch add a missing check on the return value of devm_kzalloc,
which would cause a NULL pointer dereference in a OOM situation.
Signed-off-by: Kiran Padwal <kiran.padwal@smartplayin.com>
---
drivers/net/arcnet/com20020-pci.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/net/arcnet/com20020-pci.c b/drivers/net/arcnet/com20020-pci.c
index 6c99ff0..945f532 100644
--- a/drivers/net/arcnet/com20020-pci.c
+++ b/drivers/net/arcnet/com20020-pci.c
@@ -78,6 +78,9 @@ static int com20020pci_probe(struct pci_dev *pdev, const struct pci_device_id *i
priv = devm_kzalloc(&pdev->dev, sizeof(struct com20020_priv),
GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
ci = (struct com20020_pci_card_info *)id->driver_data;
priv->ci = ci;
--
1.7.9.5
^ permalink raw reply related
* Re: [PATCH] brcmfmac: avoid duplicated suspend/resume operation
From: Fu, Zhonghui @ 2015-02-05 11:34 UTC (permalink / raw)
To: brudley, Arend van Spriel, Franky Lin, meuleman, Kalle Valo,
linville, pieterpg, hdegoede, wens, linux-wireless,
brcm80211-dev-list, netdev, linux-kernel@vger.kernel.org
In-Reply-To: <54C5AA8C.4010005@linux.intel.com>
What comments about the new patch? Can this new patch be accepted?
Thanks,
Zhonghui
On 2015/1/26 10:46, Fu, Zhonghui wrote:
> From ff39ed4af9f1c50358fe92ec4c8eaac9db183e00 Mon Sep 17 00:00:00 2001
> From: Zhonghui Fu <zhonghui.fu@linux.intel.com>
> Date: Mon, 26 Jan 2015 10:13:21 +0800
> Subject: [PATCH] brcmfmac: avoid duplicated suspend/resume operation
>
> WiFi chip has 2 SDIO functions, and PM core will trigger
> twice suspend/resume operations for one WiFi chip to do
> the same things. This patch avoid this case.
>
> Acked-by: Arend van Spriel<arend@broadcom.com>
> Signed-off-by: Zhonghui Fu <zhonghui.fu@linux.intel.com>
> ---
> drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c | 17 +++++++++++++++--
> 1 files changed, 15 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
> index 9880dae..618b545 100644
> --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
> +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
> @@ -1139,11 +1139,17 @@ void brcmf_sdio_wowl_config(struct device *dev, bool enabled)
> static int brcmf_ops_sdio_suspend(struct device *dev)
> {
> struct brcmf_bus *bus_if = dev_get_drvdata(dev);
> - struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
> + struct brcmf_sdio_dev *sdiodev;
> mmc_pm_flag_t sdio_flags;
> + struct sdio_func *func = dev_to_sdio_func(dev);
>
> brcmf_dbg(SDIO, "Enter\n");
>
> + if (func->num == 2)
> + return 0;
> +
> + sdiodev = bus_if->bus_priv.sdio;
> +
> atomic_set(&sdiodev->suspend, true);
>
> if (sdiodev->wowl_enabled) {
> @@ -1164,9 +1170,16 @@ static int brcmf_ops_sdio_suspend(struct device *dev)
> static int brcmf_ops_sdio_resume(struct device *dev)
> {
> struct brcmf_bus *bus_if = dev_get_drvdata(dev);
> - struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
> + struct brcmf_sdio_dev *sdiodev;
> + struct sdio_func *func = dev_to_sdio_func(dev);
>
> brcmf_dbg(SDIO, "Enter\n");
> +
> + if (func->num == 2)
> + return 0;
> +
> + sdiodev = bus_if->bus_priv.sdio;
> +
> if (sdiodev->pdata && sdiodev->pdata->oob_irq_supported)
> disable_irq_wake(sdiodev->pdata->oob_irq_nr);
> brcmf_sdio_wd_timer(sdiodev->bus, BRCMF_WD_POLL_MS);
> -- 1.7.1
>
^ permalink raw reply
* Re: [PATCH] brcmfmac: avoid duplicated suspend/resume operation
From: Arend van Spriel @ 2015-02-05 11:46 UTC (permalink / raw)
To: Fu, Zhonghui
Cc: brudley, Franky Lin, meuleman, Kalle Valo, linville, pieterpg,
hdegoede, wens, linux-wireless, brcm80211-dev-list, netdev,
linux-kernel@vger.kernel.org
In-Reply-To: <54D35545.7010600@linux.intel.com>
On 02/05/15 12:34, Fu, Zhonghui wrote:
> What comments about the new patch? Can this new patch be accepted?
Hi Zhonghui
Last reply from Kalle was that it did not apply to his tree and
recommended to use version numbering so "[PATCH V2] <subject>".
> Thanks,
> Zhonghui
>
> On 2015/1/26 10:46, Fu, Zhonghui wrote:
>> From ff39ed4af9f1c50358fe92ec4c8eaac9db183e00 Mon Sep 17 00:00:00 2001
>> From: Zhonghui Fu<zhonghui.fu@linux.intel.com>
>> Date: Mon, 26 Jan 2015 10:13:21 +0800
>> Subject: [PATCH] brcmfmac: avoid duplicated suspend/resume operation
>>
>> WiFi chip has 2 SDIO functions, and PM core will trigger
>> twice suspend/resume operations for one WiFi chip to do
>> the same things. This patch avoid this case.
>>
>> Acked-by: Arend van Spriel<arend@broadcom.com>
>> Signed-off-by: Zhonghui Fu<zhonghui.fu@linux.intel.com>
>> ---
And when using version info a change log here is even better. Although
admittedly I lost track which version this would be ;-)
Regards,
Arend
---
>> drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c | 17 +++++++++++++++--
>> 1 files changed, 15 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
>> index 9880dae..618b545 100644
>> --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
>> +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
>> @@ -1139,11 +1139,17 @@ void brcmf_sdio_wowl_config(struct device *dev, bool enabled)
>> static int brcmf_ops_sdio_suspend(struct device *dev)
>> {
>> struct brcmf_bus *bus_if = dev_get_drvdata(dev);
>> - struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
>> + struct brcmf_sdio_dev *sdiodev;
>> mmc_pm_flag_t sdio_flags;
>> + struct sdio_func *func = dev_to_sdio_func(dev);
>>
>> brcmf_dbg(SDIO, "Enter\n");
>>
>> + if (func->num == 2)
>> + return 0;
>> +
>> + sdiodev = bus_if->bus_priv.sdio;
>> +
>> atomic_set(&sdiodev->suspend, true);
>>
>> if (sdiodev->wowl_enabled) {
>> @@ -1164,9 +1170,16 @@ static int brcmf_ops_sdio_suspend(struct device *dev)
>> static int brcmf_ops_sdio_resume(struct device *dev)
>> {
>> struct brcmf_bus *bus_if = dev_get_drvdata(dev);
>> - struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
>> + struct brcmf_sdio_dev *sdiodev;
>> + struct sdio_func *func = dev_to_sdio_func(dev);
>>
>> brcmf_dbg(SDIO, "Enter\n");
>> +
>> + if (func->num == 2)
>> + return 0;
>> +
>> + sdiodev = bus_if->bus_priv.sdio;
>> +
>> if (sdiodev->pdata&& sdiodev->pdata->oob_irq_supported)
>> disable_irq_wake(sdiodev->pdata->oob_irq_nr);
>> brcmf_sdio_wd_timer(sdiodev->bus, BRCMF_WD_POLL_MS);
>> -- 1.7.1
>>
>
^ permalink raw reply
* Re: [PATCH] brcmfmac: avoid duplicated suspend/resume operation
From: Fu, Zhonghui @ 2015-02-05 11:56 UTC (permalink / raw)
To: Kalle Valo
Cc: brudley, Arend van Spriel, Franky Lin, meuleman, linville,
pieterpg, hdegoede, wens, linux-wireless, brcm80211-dev-list,
netdev, linux-kernel@vger.kernel.org
In-Reply-To: <87vbjjw3bc.fsf@kamboji.qca.qualcomm.com>
On 2015/2/3 21:08, Kalle Valo wrote:
> "Fu, Zhonghui" <zhonghui.fu@linux.intel.com> writes:
>
>> >From ff39ed4af9f1c50358fe92ec4c8eaac9db183e00 Mon Sep 17 00:00:00 2001
>> From: Zhonghui Fu <zhonghui.fu@linux.intel.com>
>> Date: Mon, 26 Jan 2015 10:13:21 +0800
>> Subject: [PATCH] brcmfmac: avoid duplicated suspend/resume operation
>>
>> WiFi chip has 2 SDIO functions, and PM core will trigger
>> twice suspend/resume operations for one WiFi chip to do
>> the same things. This patch avoid this case.
>>
>> Acked-by: Arend van Spriel<arend@broadcom.com>
>> Signed-off-by: Zhonghui Fu <zhonghui.fu@linux.intel.com>
> This doesn't apply:
>
> Applying: brcmfmac: avoid duplicated suspend/resume operation
> Using index info to reconstruct a base tree...
> Falling back to patching base and 3-way merge...
> Auto-merging drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
> CONFLICT (content): Merge conflict in drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
> Failed to merge in the changes.
> Patch failed at 0001 brcmfmac: avoid duplicated suspend/resume operation
>
> BTW, when you resend a patch please use "[PATCH v2]" (or v3, v4...) in
> the Subject field.
Just see your comments, so please ignore my inquiry in last mail. I will re-base this patch again.
Thanks,
Zhonghui
^ permalink raw reply
* Re: [PATCH] NetCP: Deletion of unnecessary checks before two function calls
From: Dan Carpenter @ 2015-02-05 12:01 UTC (permalink / raw)
To: Wingman Kwok
Cc: SF Markus Elfring, Murali Karicheri, Wingman Kwok, netdev, LKML,
kernel-janitors, Julia Lawall
In-Reply-To: <54D11FEF.10804@users.sourceforge.net>
Hi Wingman,
There are some bugs in this error handling.
On Tue, Feb 03, 2015 at 08:22:23PM +0100, SF Markus Elfring wrote:
> diff --git a/drivers/net/ethernet/ti/netcp_ethss.c b/drivers/net/ethernet/ti/netcp_ethss.c
> index fa1041a..cbd6dde 100644
> --- a/drivers/net/ethernet/ti/netcp_ethss.c
> +++ b/drivers/net/ethernet/ti/netcp_ethss.c
> @@ -2010,12 +2010,10 @@ static int gbe_probe(struct netcp_device *netcp_device, struct device *dev,
> quit:
> if (gbe_dev->hw_stats)
> devm_kfree(dev, gbe_dev->hw_stats);
> - if (gbe_dev->ale)
> - cpsw_ale_destroy(gbe_dev->ale);
> + cpsw_ale_destroy(gbe_dev->ale);
> if (gbe_dev->ss_regs)
> devm_iounmap(dev, gbe_dev->ss_regs);
> - if (interfaces)
> - of_node_put(interfaces);
> + of_node_put(interfaces);
^^^^^^^^^^
"interfaces" is sometimes unintialized in this code. I don't know why
GCC doesn't catch this... :(
This is a "one rrr bug", which is caused because you just have one error
label "quit" which handles all the error handling. Please read my
Google+ comment on error handling.
https://plus.google.com/106378716002406849458/posts/dnanfhQ4mHQ
> devm_kfree(dev, gbe_dev);
^^^^^^^^^^^^^^^^^^^^^^^^
This is not the right way to use the devm_ interface. These things are
freed automatically on error or when we are done with them. This driver
is double freeing pretty much everything. Grep for devm_kfree() and
fix everything.
I don't know why kbuild didn't catch this...
regards
dan carpenter
^ permalink raw reply
* Re: [PATCH 1/1] neighbour: Support broadcast ARP in neighbor PROPE state
From: Sergei Shtylyov @ 2015-02-05 12:12 UTC (permalink / raw)
To: zhuyj, netdev, stefan.costandache, alexandre.dietsch, yue.tao,
clinton.slabbert
Cc: eulfsam, David S. Miller, WANG Cong
In-Reply-To: <1423120837-28102-1-git-send-email-zyjzyj2000@gmail.com>
Hello.
On 2/5/2015 10:20 AM, zhuyj wrote:
> From: eulfsam <ulf.samuelsson@ericsson.com>
> When the neighbor statemachine is in PROBE state, it will normally send
State machine.
> a number of unicast ARP requests (number defined in "ucast_probes" entry
> in the proc file system, default=3) and if no reply is received, it will
> change state to FAILED.
> Enabling CONFIG_ARP_PROBE_BCAST, will make the statemachine try to send
Likewise.
> broadcast ARP requests, and only enter FAILED state if the broadcast ARP
> requests did not receive a reply.
> Enabling CONFIG_ARP_PROBE_BCAST, makes the IPv4 ARP behaviour more
> similar to the IPv6 Neighbor Discovery protocol, and is neccessary,
Necessary.
> if the other end only responds to broadcast ARPs.
> CC: David S. Miller <davem@davemloft.net>
> CC: WANG Cong <xiyou.wangcong@gmail.com>
> Signed-off-by: eulfsam <ulf.samuelsson@ericsson.com>
> Signed-off-by: zhuyj <zyjzyj2000@gmail.com>
Need real names here.
[...]
> diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig
> index bd29016..4d13edb 100644
> --- a/net/ipv4/Kconfig
> +++ b/net/ipv4/Kconfig
> @@ -259,6 +259,23 @@ config IP_PIMSM_V2
> gated-5). This routing protocol is not used widely, so say N unless
> you want to play with it.
>
> +config ARP_PROBE_BCAST
> + bool "IP: ARP send broadcast ARP, if probing using unicast fails"
> + default y
> + ---help---
> + When the neighbor statemachine is in PROBE state, it will
State machine.
> + normally send a number of unicast ARP requests
> + (number defined in "ucast_probes" entry in the proc file system, default=3)
> + and if no reply is received, it will change state to FAILED.
> +
> + Saying Y here, will make the statemachine try to send broadcast ARP
Likewise.
> + requests, and only enter FAILED state if the broadcast ARP requests did not
> + receive a reply.
> +
> + Enabling this, makes the IPv4 ARP behaviour more similar to the IPv6
> + Neighbor Discovery protocol, and is neccessary, if the other end
Necessary.
[...]
WBR, Sergei
^ permalink raw reply
* Re: [PATCH v2] net: bluetooth: hci_sock: Use 'const void *' instead of 'void *' for 2nd parameter of hci_test_bit()
From: Chen Gang S @ 2015-02-05 12:20 UTC (permalink / raw)
To: David Laight, Marcel Holtmann, Sergei Shtylyov
Cc: Gustavo F. Padovan, Johan Hedberg, David S. Miller,
linux-bluetooth@vger.kernel.org, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org
In-Reply-To: <063D6719AE5E284EB5DD2968C1650D6D1CADC42B@AcuExch.aculab.com>
On 2/5/15 18:14, David Laight wrote:
> From: Chen Gang S [mailto:gang.chen@sunrus.com.cn]
>> On 2/5/15 05:09, Marcel Holtmann wrote:
>>> Hi Sergei,
>>>
>>>>>> -static inline int hci_test_bit(int nr, void *addr)
>>>>>> +static inline int hci_test_bit(int nr, const void *addr)
>>>>>> {
>>>>>> return *((__u32 *) addr + (nr >> 5)) & ((__u32) 1 << (nr & 31));
>>>>>> }
>>>>
>>>>> Is there a 'standard' function lurking that will do the above.
>>>>> On x86 the cpus 'bit test' instruction will handle bit numbers
>>>>> greater than the word size - so it can be a single instruction.
>>>>
>>>> Of course, there's test_bit().
>>>
>>> we did leave hci_test_bit in the code since there are some userspace facing
>>> API that we can not change. Remember that the origin of this code is
>>> from 2.4.6 kernel.
>>>
>>> So we can only change this if you can ensure not to break the userspace API.
>>> So might want to write unit tests to ensure working HCI filter before even
>>> considering touching this.
>>>
>>
>> For me, we have to remain hci_test_bit(), it is for "__u32 *" (which we
>> can not change). The common test_bit() is for "unsigned long *", in this
>> case, I guess it may cause issue under 64-bit environments.
>
> Except that half the time you are passing a 'long *' and you haven't
> explained why this isn't broken on 64bit architectures.
>
Maybe we are misunderstanding with each other (excuse me for my pool
English). What I want to say is:
- hci_test_bit() is OK (current implementation can not cause issue for
64-bit machine).
- But if we use test_bit(), I guess it will cause issue for 64-bit
machine.
> Note that on LE systems the size of the accesses used to access a dense
> bit array don't matter. This is not true of BE systems.
>
Yes, what you said above sounds reasonable to me, too.
Thanks.
--
Chen Gang
Open, share, and attitude like air, water, and life which God blessed
^ permalink raw reply
* Re: Throughput regression with `tcp: refine TSO autosizing`
From: Eric Dumazet @ 2015-02-05 12:57 UTC (permalink / raw)
To: Michal Kazior; +Cc: Neal Cardwell, linux-wireless, Network Development, eyalpe
In-Reply-To: <CA+BoTQnnwrv0nrKyGyQNvosz_E4e5fBa9iN8fpeqcd-iRfi17g@mail.gmail.com>
On Thu, 2015-02-05 at 09:38 +0100, Michal Kazior wrote:
> On 4 February 2015 at 22:11, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> > I do not see how a TSO patch could hurt a flow not using TSO/GSO.
> >
> > This makes no sense.
>
> Hmm..
>
> @@ -2018,8 +2053,8 @@ static bool tcp_write_xmit(struct sock *sk,
> unsigned int mss_now, int nonagle,
> * of queued bytes to ensure line rate.
> * One example is wifi aggregation (802.11 AMPDU)
> */
> - limit = max_t(unsigned int, sysctl_tcp_limit_output_bytes,
> - sk->sk_pacing_rate >> 10);
> + limit = max(2 * skb->truesize, sk->sk_pacing_rate >> 10);
> + limit = min_t(u32, limit, sysctl_tcp_limit_output_bytes);
>
> if (atomic_read(&sk->sk_wmem_alloc) > limit) {
> set_bit(TSQ_THROTTLED, &tp->tsq_flags);
>
> Doesn't this effectively invert how tcp_limit_output_bytes is used?
> This would explain why raising the limit wasn't changing anything
> anymore when you asked me do so. Only decreasing it yielded any
> change.
>
> I've added a printk to show up the new and old values. Excerpt from logs:
>
> [ 114.782740] (4608 39126 131072 = 39126) vs (131072 39126 = 131072)
>
> (2*truesize, pacing_rate, tcp_limit = limit) vs (tcp_limit, pacing_rate = limit)
>
> Reverting this patch hunk alone fixes my TCP problem. Not that I'm
> saying the old logic was correct (it seems it wasn't, a limit should
> be applied as min(value, max_value), right?).
>
> Anyway the change doesn't seem to be TSO-only oriented so it would
> explain the "makes no sense".
The intention is to control the queues to the following :
1 ms of buffering, but limited to a configurable value.
On a 40Gbps flow, 1ms represents 5 MB, which is insane.
We do not want to queue 5 MB of traffic, this would destroy latencies
for all concurrent flows. (Or would require having fq_codel or fq as
packet schedulers, instead of default pfifo_fast)
This is why having 1.5 ms delay between the transmit and TX completion
is a problem in your case.
^ permalink raw reply
* Re: Throughput regression with `tcp: refine TSO autosizing`
From: Eric Dumazet @ 2015-02-05 13:03 UTC (permalink / raw)
To: Michal Kazior
Cc: Neal Cardwell, linux-wireless, Network Development,
eyalpe-LDSdmyG8hGV8YrgS2mwiifqBs+8SCbDb
In-Reply-To: <CA+BoTQnwcmu=YbKB17JQb7ZPwGZoQS7zQ6nT-WEJHjnBX34QKA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On Thu, 2015-02-05 at 07:46 +0100, Michal Kazior wrote:
> On 4 February 2015 at 22:11, Eric Dumazet <eric.dumazet-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> > Most conservative patch would be :
> >
> > diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c
> > index 9c782a42665e1aaf43bfbca441631ee58da50c09..6a36317d6bb0447202dee15528130bd5e21248c4 100644
> > --- a/drivers/net/wireless/ath/ath10k/htt_rx.c
> > +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
> > @@ -1642,6 +1642,7 @@ void ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb)
> > break;
> > }
> > case HTT_T2H_MSG_TYPE_TX_COMPL_IND:
> > + skb_orphan(skb);
> > spin_lock_bh(&htt->tx_lock);
> > __skb_queue_tail(&htt->tx_compl_q, skb);
> > spin_unlock_bh(&htt->tx_lock);
>
> I suppose you want to call skb_orphan() on actual data packets, right?
> This skb is just a host-firmware communication buffer.
Right. I have no idea how you find the actual data packet at this stage.
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* NetDev 0.1 final schedule and new sponsor update
From: Richard Guy Briggs @ 2015-02-05 13:05 UTC (permalink / raw)
To: netdev, linux-wireless, lwn, netdev01, lartc, netfilter,
netfilter-devel
Cc: info, speakers, attendees
Fellow netheads:
New Sponsor:
==========================
We thank Intel for supporting Netdev01. Intel is well known in its
tradition for supporting open source projects. http://www.intel.com/
Schedule:
==========================
The final schedule is out coded with session links.
https://www.netdev01.org/schedule
Registration:
==========================
https://onlineregistrations.ca/netdev01/
$100/day, or $350 for 4 days (Cdn dollars). (online reg closes Feb 12th)
Please register as early as practical. Registering helps us plan properly for
numbers of attendees, ensuring venue sizes and supplies are appropriate without
wasting resources.
Hotel discount rates deadline extended
==========================
The Westin Hotel may still have rooms for Netdev01 available.
There are lots of big and small hotels in Ottawa, but they will fill up
fast as Winterlude approaches, so book something soon. There may be
some possibilities to billet locally, but don't leave it last minute.
Make your reservations at:
https://www.starwoodmeeting.com/StarGroupsWeb/res?id=1412035802&key=1AC9C1F8
Sponsors:
=========
NetDev 0.1 would like to gratefully acknowledge all our sponsors:
https://netdev01.org/sponsors
CENGN http://www.cengn.ca/
Google https://www.google.ca
Qualcomm https://www.qualcomm.com/
Verizon http://www.verizon.com/
Cumulus Networks http://cumulusnetworks.com/
Mojatatu Networks http://mojatatu.com/
-------------------------------------------------------------------------------
THE Technical Conference on Linux Networking, February 14-17, 2015, Ottawa, Canada
https://netdev01.org/
Contact: info@netdev01.info
Main site: https://www.netdev01.org/
Travel/hotel/weather/clothing: https://www.netdev01.org/travel
RSS feed: https://netdev01.org/atom
Follow us on Twitter: @netdev01 https://twitter.com/netdev01
^ permalink raw reply
* Re: [RFC PATCH net-next 00/11] net: remove disable_irq() from ->ndo_poll_controller
From: Peter Zijlstra @ 2015-02-05 13:06 UTC (permalink / raw)
To: Sabrina Dubroca; +Cc: Thomas Gleixner, David Miller, netdev
In-Reply-To: <20150205002059.GA28282@kria>
On Thu, Feb 05, 2015 at 01:20:59AM +0100, Sabrina Dubroca wrote:
> Thomas, ping?
>
> thread is over there if you need it:
> https://marc.info/?l=linux-netdev&m=141833435000554&w=2
It appears to me you have addressed most his issues and since it appears
to me the existing synchronze_hardirq() seems to be mostly what we need
I'll propose (and merge) the below and will take flames from tglx when
he returns :-)
---
Subject: genirq: Provide disable_hardirq()
For things like netpoll there is a need to disable an interrupt from
atomic context. Currently netpoll uses disable_irq() which will
sleep-wait on threaded handlers and thus forced_irqthreads breaks
things.
Provide disable_hardirq(), which uses synchronize_hardirq() to only wait
for active hardirq handlers; also change synchronize_hardirq() to
return the status of threaded handlers.
This will allow one to try-disable an interrupt from atomic context, or
in case of request_threaded_irq() to only wait for the hardirq part.
Suggested-by: Sabrina Dubroca <sd@queasysnail.net>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
include/linux/hardirq.h | 2 +-
include/linux/interrupt.h | 1 +
kernel/irq/manage.c | 36 ++++++++++++++++++++++++++++++++++--
3 files changed, 36 insertions(+), 3 deletions(-)
diff --git a/include/linux/hardirq.h b/include/linux/hardirq.h
index cba442ec3c66..f4af03404b97 100644
--- a/include/linux/hardirq.h
+++ b/include/linux/hardirq.h
@@ -9,7 +9,7 @@
extern void synchronize_irq(unsigned int irq);
-extern void synchronize_hardirq(unsigned int irq);
+extern bool synchronize_hardirq(unsigned int irq);
#if defined(CONFIG_TINY_RCU)
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index d9b05b5bf8c7..3bb01b9a379c 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -184,6 +184,7 @@ extern void devm_free_irq(struct device *dev, unsigned int irq, void *dev_id);
#endif
extern void disable_irq_nosync(unsigned int irq);
+extern bool disable_hardirq(unsigned int irq);
extern void disable_irq(unsigned int irq);
extern void disable_percpu_irq(unsigned int irq);
extern void enable_irq(unsigned int irq);
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index f038e586a4b9..1309cccd714f 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -68,14 +68,20 @@ static void __synchronize_hardirq(struct irq_desc *desc)
* Do not use this for shutdown scenarios where you must be sure
* that all parts (hardirq and threaded handler) have completed.
*
+ * Returns: false if a theaded handler is active.
+ *
* This function may be called - with care - from IRQ context.
*/
-void synchronize_hardirq(unsigned int irq)
+bool synchronize_hardirq(unsigned int irq)
{
struct irq_desc *desc = irq_to_desc(irq);
- if (desc)
+ if (desc) {
__synchronize_hardirq(desc);
+ return !atomic_read(&desc->threads_active);
+ }
+
+ return true;
}
EXPORT_SYMBOL(synchronize_hardirq);
@@ -439,6 +445,32 @@ void disable_irq(unsigned int irq)
}
EXPORT_SYMBOL(disable_irq);
+/**
+ * disable_hardirq - disables an irq and waits for hardirq completion
+ * @irq: Interrupt to disable
+ *
+ * Disable the selected interrupt line. Enables and Disables are
+ * nested.
+ * This function waits for any pending hard IRQ handlers for this
+ * interrupt to complete before returning. If you use this function while
+ * holding a resource the hard IRQ handler may need you will deadlock.
+ *
+ * When used to optimistically disable an interrupt from atomic context
+ * the return value must be checked.
+ *
+ * Returns: false if a theaded handler is active.
+ *
+ * This function may be called - with care - from IRQ context.
+ */
+bool disable_hardirq(unsigned int irq)
+{
+ if (!__disable_irq_nosync(irq))
+ return synchronize_hardirq(irq);
+
+ return false;
+}
+EXPORT_SYMBOL(disable_hardirq);
+
void __enable_irq(struct irq_desc *desc, unsigned int irq)
{
switch (desc->depth) {
^ permalink raw reply related
* Re: [PATCH v2] socket.7: add description for SO_BUSY_POLL
From: Michael Kerrisk (man-pages) @ 2015-02-05 13:17 UTC (permalink / raw)
To: Eliezer Tamir
Cc: linux-man, David Miller, lkml, netdev, Andrew Morton,
Eliezer Tamir
In-Reply-To: <52DD5CC4.3010708@linux.intel.com>
On 20 January 2014 at 18:28, Eliezer Tamir
<eliezer.tamir@linux.intel.com> wrote:
> On 20/01/2014 18:28, Michael Kerrisk (man-pages) wrote:
>> On 07/10/2013 04:18 PM, Eliezer Tamir wrote:
>>> Add description for the SO_BUSY_POLL socket option to the socket(7) manpage.
>>
>> Long after the fact, I've applied this. Thanks, Eliezer.
>>
>> Would you be willing also to write a patch for the POLL_BUSY_LOOP flag of
>> poll()?
>
> Yes, Me or someone from our team will do that.
Hi Eliezer,
Could you or someone from your team send me a POLL_BUSY_LOOP doc patch?
Thanks,
Michael
--
Michael Kerrisk
Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/
Linux/UNIX System Programming Training: http://man7.org/training/
^ permalink raw reply
* Re: Throughput regression with `tcp: refine TSO autosizing`
From: Eric Dumazet @ 2015-02-05 13:19 UTC (permalink / raw)
To: Michal Kazior; +Cc: Neal Cardwell, linux-wireless, Network Development, eyalpe
In-Reply-To: <1423141038.31870.38.camel@edumazet-glaptop2.roam.corp.google.com>
On Thu, 2015-02-05 at 04:57 -0800, Eric Dumazet wrote:
> The intention is to control the queues to the following :
>
> 1 ms of buffering, but limited to a configurable value.
>
> On a 40Gbps flow, 1ms represents 5 MB, which is insane.
>
> We do not want to queue 5 MB of traffic, this would destroy latencies
> for all concurrent flows. (Or would require having fq_codel or fq as
> packet schedulers, instead of default pfifo_fast)
>
> This is why having 1.5 ms delay between the transmit and TX completion
> is a problem in your case.
Note that TCP stack could detect when this happens, *if* ACK where
delivered before the TX completions, or when TX completion happens,
we could detect that the clone of the freed packet was freed.
In my test, when I did "ethtool -C eth0 tx-usecs 1024 tx-frames 64", and
disabling GSO, TCP stack sends a bunch of packets (a bit less than 64),
blocks on tcp_limit_output_bytes.
Then we receive 2 stretch ACKS after ~50 usec.
TCP stack tries to push again some packets but blocks on
tcp_limit_output_bytes again.
1ms later, TX completion happens, tcp_wfree() is called, and TCP stack
push following ~60 packets.
TCP could eventually dynamically adjust the tcp_limit_output_bytes,
using a per flow dynamic value, but I would rather not add a kludge in
TCP stack only to deal with a possible bug in ath10k driver.
niu has a similar issue and simply had to call skb_orphan() :
drivers/net/ethernet/sun/niu.c:6669: skb_orphan(skb);
^ permalink raw reply
* Re: Throughput regression with `tcp: refine TSO autosizing`
From: Eric Dumazet @ 2015-02-05 13:33 UTC (permalink / raw)
To: Michal Kazior
Cc: Neal Cardwell, linux-wireless, Network Development,
eyalpe-LDSdmyG8hGV8YrgS2mwiifqBs+8SCbDb
In-Reply-To: <1423142342.31870.49.camel-XN9IlZ5yJG9HTL0Zs8A6p/gx64E7kk8eUsxypvmhUTTZJqsBc5GL+g@public.gmane.org>
On Thu, 2015-02-05 at 05:19 -0800, Eric Dumazet wrote:
>
> TCP could eventually dynamically adjust the tcp_limit_output_bytes,
> using a per flow dynamic value, but I would rather not add a kludge in
> TCP stack only to deal with a possible bug in ath10k driver.
>
> niu has a similar issue and simply had to call skb_orphan() :
>
> drivers/net/ethernet/sun/niu.c:6669: skb_orphan(skb);
In your case that might be the place :
diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c
index 4bc51d8a14a3..cbda7a87d5a1 100644
--- a/drivers/net/wireless/ath/ath10k/htt_tx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_tx.c
@@ -468,6 +468,7 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
msdu_id = res;
htt->pending_tx[msdu_id] = msdu;
spin_unlock_bh(&htt->tx_lock);
+ skb_orphan(msdu);
prefetch_len = min(htt->prefetch_len, msdu->len);
prefetch_len = roundup(prefetch_len, 4);
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH net-next 2/9] tipc: simplify message forwarding and rejection in socket layer
From: Jon Maloy @ 2015-02-05 13:36 UTC (permalink / raw)
To: davem; +Cc: Jon Maloy, netdev, Paul Gortmaker, tipc-discussion
In-Reply-To: <1423143404-23322-1-git-send-email-jon.maloy@ericsson.com>
Despite recent improvements, the handling of error codes and return
values at reception of messages in the socket layer is still confusing.
In this commit, we try to make it more comprehensible. First, we
separate between the return values coming from the functions called
by tipc_sk_rcv(), -those are TIPC specific error codes, and the
return values returned by tipc_sk_rcv() itself. Second, we don't
use the returned TIPC error code as indication for whether a buffer
should be forwarded/rejected or not; instead we use the buffer pointer
passed along with filter_msg(). This separation is necessary because
we sometimes want to forward messages even when there is no error
(i.e., protocol messages and successfully secondary looked up data
messages).
Reviewed-by: Ying Xue <ying.xue@windriver.com>
Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
---
net/tipc/socket.c | 120 ++++++++++++++++++++++++++----------------------------
1 file changed, 58 insertions(+), 62 deletions(-)
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index b384e65..f9cd587 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -818,17 +818,14 @@ void tipc_sk_mcast_rcv(struct net *net, struct sk_buff *buf)
/**
* tipc_sk_proto_rcv - receive a connection mng protocol message
* @tsk: receiving socket
- * @dnode: node to send response message to, if any
- * @buf: buffer containing protocol message
- * Returns 0 (TIPC_OK) if message was consumed, 1 (TIPC_FWD_MSG) if
- * (CONN_PROBE_REPLY) message should be forwarded.
+ * @skb: pointer to message buffer. Set to NULL if buffer is consumed.
*/
-static int tipc_sk_proto_rcv(struct tipc_sock *tsk, u32 *dnode,
- struct sk_buff *buf)
+static void tipc_sk_proto_rcv(struct tipc_sock *tsk, struct sk_buff **skb)
{
- struct tipc_msg *msg = buf_msg(buf);
+ struct tipc_msg *msg = buf_msg(*skb);
int conn_cong;
-
+ u32 dnode;
+ u32 own_node = tsk_own_node(tsk);
/* Ignore if connection cannot be validated: */
if (!tsk_peer_msg(tsk, msg))
goto exit;
@@ -841,15 +838,15 @@ static int tipc_sk_proto_rcv(struct tipc_sock *tsk, u32 *dnode,
if (conn_cong)
tsk->sk.sk_write_space(&tsk->sk);
} else if (msg_type(msg) == CONN_PROBE) {
- if (!tipc_msg_reverse(tsk_own_node(tsk), buf, dnode, TIPC_OK))
- return TIPC_OK;
- msg_set_type(msg, CONN_PROBE_REPLY);
- return TIPC_FWD_MSG;
+ if (tipc_msg_reverse(own_node, *skb, &dnode, TIPC_OK)) {
+ msg_set_type(msg, CONN_PROBE_REPLY);
+ return;
+ }
}
/* Do nothing if msg_type() == CONN_PROBE_REPLY */
exit:
- kfree_skb(buf);
- return TIPC_OK;
+ kfree_skb(*skb);
+ *skb = NULL;
}
static int tipc_wait_for_sndmsg(struct socket *sock, long *timeo_p)
@@ -1568,16 +1565,16 @@ static void tipc_data_ready(struct sock *sk)
/**
* filter_connect - Handle all incoming messages for a connection-based socket
* @tsk: TIPC socket
- * @msg: message
+ * @skb: pointer to message buffer. Set to NULL if buffer is consumed
*
* Returns 0 (TIPC_OK) if everything ok, -TIPC_ERR_NO_PORT otherwise
*/
-static int filter_connect(struct tipc_sock *tsk, struct sk_buff **buf)
+static int filter_connect(struct tipc_sock *tsk, struct sk_buff **skb)
{
struct sock *sk = &tsk->sk;
struct net *net = sock_net(sk);
struct socket *sock = sk->sk_socket;
- struct tipc_msg *msg = buf_msg(*buf);
+ struct tipc_msg *msg = buf_msg(*skb);
int retval = -TIPC_ERR_NO_PORT;
if (msg_mcast(msg))
@@ -1627,8 +1624,8 @@ static int filter_connect(struct tipc_sock *tsk, struct sk_buff **buf)
* connect() routine if sleeping.
*/
if (msg_data_sz(msg) == 0) {
- kfree_skb(*buf);
- *buf = NULL;
+ kfree_skb(*skb);
+ *skb = NULL;
if (waitqueue_active(sk_sleep(sk)))
wake_up_interruptible(sk_sleep(sk));
}
@@ -1680,32 +1677,33 @@ static unsigned int rcvbuf_limit(struct sock *sk, struct sk_buff *buf)
/**
* filter_rcv - validate incoming message
* @sk: socket
- * @buf: message
+ * @skb: pointer to message. Set to NULL if buffer is consumed.
*
* Enqueues message on receive queue if acceptable; optionally handles
* disconnect indication for a connected socket.
*
- * Called with socket lock already taken; port lock may also be taken.
+ * Called with socket lock already taken
*
- * Returns 0 (TIPC_OK) if message was consumed, -TIPC error code if message
- * to be rejected, 1 (TIPC_FWD_MSG) if (CONN_MANAGER) message to be forwarded
+ * Returns 0 (TIPC_OK) if message was ok, -TIPC error code if rejected
*/
-static int filter_rcv(struct sock *sk, struct sk_buff *buf)
+static int filter_rcv(struct sock *sk, struct sk_buff **skb)
{
struct socket *sock = sk->sk_socket;
struct tipc_sock *tsk = tipc_sk(sk);
- struct tipc_msg *msg = buf_msg(buf);
- unsigned int limit = rcvbuf_limit(sk, buf);
- u32 onode;
+ struct tipc_msg *msg = buf_msg(*skb);
+ unsigned int limit = rcvbuf_limit(sk, *skb);
int rc = TIPC_OK;
- if (unlikely(msg_user(msg) == CONN_MANAGER))
- return tipc_sk_proto_rcv(tsk, &onode, buf);
+ if (unlikely(msg_user(msg) == CONN_MANAGER)) {
+ tipc_sk_proto_rcv(tsk, skb);
+ return TIPC_OK;
+ }
if (unlikely(msg_user(msg) == SOCK_WAKEUP)) {
- kfree_skb(buf);
+ kfree_skb(*skb);
tsk->link_cong = 0;
sk->sk_write_space(sk);
+ *skb = NULL;
return TIPC_OK;
}
@@ -1717,21 +1715,22 @@ static int filter_rcv(struct sock *sk, struct sk_buff *buf)
if (msg_connected(msg))
return -TIPC_ERR_NO_PORT;
} else {
- rc = filter_connect(tsk, &buf);
- if (rc != TIPC_OK || buf == NULL)
+ rc = filter_connect(tsk, skb);
+ if (rc != TIPC_OK || !*skb)
return rc;
}
/* Reject message if there isn't room to queue it */
- if (sk_rmem_alloc_get(sk) + buf->truesize >= limit)
+ if (sk_rmem_alloc_get(sk) + (*skb)->truesize >= limit)
return -TIPC_ERR_OVERLOAD;
/* Enqueue message */
- TIPC_SKB_CB(buf)->handle = NULL;
- __skb_queue_tail(&sk->sk_receive_queue, buf);
- skb_set_owner_r(buf, sk);
+ TIPC_SKB_CB(*skb)->handle = NULL;
+ __skb_queue_tail(&sk->sk_receive_queue, *skb);
+ skb_set_owner_r(*skb, sk);
sk->sk_data_ready(sk);
+ *skb = NULL;
return TIPC_OK;
}
@@ -1746,25 +1745,22 @@ static int filter_rcv(struct sock *sk, struct sk_buff *buf)
*/
static int tipc_backlog_rcv(struct sock *sk, struct sk_buff *skb)
{
- int rc;
- u32 onode;
+ int err;
+ atomic_t *dcnt;
+ u32 dnode;
struct tipc_sock *tsk = tipc_sk(sk);
struct net *net = sock_net(sk);
uint truesize = skb->truesize;
- rc = filter_rcv(sk, skb);
-
- if (likely(!rc)) {
- if (atomic_read(&tsk->dupl_rcvcnt) < TIPC_CONN_OVERLOAD_LIMIT)
- atomic_add(truesize, &tsk->dupl_rcvcnt);
+ err = filter_rcv(sk, &skb);
+ if (likely(!skb)) {
+ dcnt = &tsk->dupl_rcvcnt;
+ if (atomic_read(dcnt) < TIPC_CONN_OVERLOAD_LIMIT)
+ atomic_add(truesize, dcnt);
return 0;
}
-
- if ((rc < 0) && !tipc_msg_reverse(tsk_own_node(tsk), skb, &onode, -rc))
- return 0;
-
- tipc_link_xmit_skb(net, skb, onode, 0);
-
+ if (!err || tipc_msg_reverse(tsk_own_node(tsk), skb, &dnode, -err))
+ tipc_link_xmit_skb(net, skb, dnode, tsk->portid);
return 0;
}
@@ -1780,14 +1776,14 @@ int tipc_sk_rcv(struct net *net, struct sk_buff *skb)
struct tipc_net *tn;
struct sock *sk;
u32 dport = msg_destport(buf_msg(skb));
- int rc = TIPC_OK;
+ int err = TIPC_OK;
uint limit;
u32 dnode;
/* Validate destination and message */
tsk = tipc_sk_lookup(net, dport);
if (unlikely(!tsk)) {
- rc = tipc_msg_eval(net, skb, &dnode);
+ err = tipc_msg_eval(net, skb, &dnode);
goto exit;
}
sk = &tsk->sk;
@@ -1796,25 +1792,25 @@ int tipc_sk_rcv(struct net *net, struct sk_buff *skb)
spin_lock_bh(&sk->sk_lock.slock);
if (!sock_owned_by_user(sk)) {
- rc = filter_rcv(sk, skb);
+ err = filter_rcv(sk, &skb);
} else {
if (sk->sk_backlog.len == 0)
atomic_set(&tsk->dupl_rcvcnt, 0);
limit = rcvbuf_limit(sk, skb) + atomic_read(&tsk->dupl_rcvcnt);
- if (sk_add_backlog(sk, skb, limit))
- rc = -TIPC_ERR_OVERLOAD;
+ if (likely(!sk_add_backlog(sk, skb, limit)))
+ skb = NULL;
+ else
+ err = -TIPC_ERR_OVERLOAD;
}
spin_unlock_bh(&sk->sk_lock.slock);
sock_put(sk);
- if (likely(!rc))
- return 0;
exit:
- tn = net_generic(net, tipc_net_id);
- if ((rc < 0) && !tipc_msg_reverse(tn->own_addr, skb, &dnode, -rc))
- return -EHOSTUNREACH;
-
- tipc_link_xmit_skb(net, skb, dnode, 0);
- return (rc < 0) ? -EHOSTUNREACH : 0;
+ if (unlikely(skb)) {
+ tn = net_generic(net, tipc_net_id);
+ if (!err || tipc_msg_reverse(tn->own_addr, skb, &dnode, -err))
+ tipc_link_xmit_skb(net, skb, dnode, 0);
+ }
+ return err ? -EHOSTUNREACH : 0;
}
static int tipc_wait_for_connect(struct socket *sock, long *timeo_p)
--
1.9.1
------------------------------------------------------------------------------
Dive into the World of Parallel Programming. The Go Parallel Website,
sponsored by Intel and developed in partnership with Slashdot Media, is your
hub for all things parallel software development, from weekly thought
leadership blogs to news, videos, case studies, tutorials and more. Take a
look and join the conversation now. http://goparallel.sourceforge.net/
^ permalink raw reply related
* [PATCH net-next 3/9] tipc: enqueue arrived buffers in socket in separate function
From: Jon Maloy @ 2015-02-05 13:36 UTC (permalink / raw)
To: davem; +Cc: Jon Maloy, netdev, Paul Gortmaker, tipc-discussion
In-Reply-To: <1423143404-23322-1-git-send-email-jon.maloy@ericsson.com>
The code for enqueuing arriving buffers in the function tipc_sk_rcv()
contains long code lines and currently goes to two indentation levels.
As a cosmetic preparaton for the next commits, we break it out into
a separate function.
Reviewed-by: Ying Xue <ying.xue@windriver.com>
Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
---
net/tipc/socket.c | 46 +++++++++++++++++++++++++++++++---------------
1 file changed, 31 insertions(+), 15 deletions(-)
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index f9cd587..1d98bfc 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -1765,6 +1765,35 @@ static int tipc_backlog_rcv(struct sock *sk, struct sk_buff *skb)
}
/**
+ * tipc_sk_enqueue_skb - enqueue buffer to socket or backlog queue
+ * @sk: socket
+ * @skb: pointer to message. Set to NULL if buffer is consumed.
+ * @dnode: if buffer should be forwarded/returned, send to this node
+ *
+ * Caller must hold socket lock
+ *
+ * Returns TIPC_OK (0) or -tipc error code
+ */
+static int tipc_sk_enqueue_skb(struct sock *sk, struct sk_buff **skb)
+{
+ unsigned int lim;
+ atomic_t *dcnt;
+
+ if (unlikely(!*skb))
+ return TIPC_OK;
+ if (!sock_owned_by_user(sk))
+ return filter_rcv(sk, skb);
+ dcnt = &tipc_sk(sk)->dupl_rcvcnt;
+ if (sk->sk_backlog.len)
+ atomic_set(dcnt, 0);
+ lim = rcvbuf_limit(sk, *skb) + atomic_read(dcnt);
+ if (unlikely(sk_add_backlog(sk, *skb, lim)))
+ return -TIPC_ERR_OVERLOAD;
+ *skb = NULL;
+ return TIPC_OK;
+}
+
+/**
* tipc_sk_rcv - handle incoming message
* @skb: buffer containing arriving message
* Consumes buffer
@@ -1776,8 +1805,7 @@ int tipc_sk_rcv(struct net *net, struct sk_buff *skb)
struct tipc_net *tn;
struct sock *sk;
u32 dport = msg_destport(buf_msg(skb));
- int err = TIPC_OK;
- uint limit;
+ int err;
u32 dnode;
/* Validate destination and message */
@@ -1788,20 +1816,8 @@ int tipc_sk_rcv(struct net *net, struct sk_buff *skb)
}
sk = &tsk->sk;
- /* Queue message */
spin_lock_bh(&sk->sk_lock.slock);
-
- if (!sock_owned_by_user(sk)) {
- err = filter_rcv(sk, &skb);
- } else {
- if (sk->sk_backlog.len == 0)
- atomic_set(&tsk->dupl_rcvcnt, 0);
- limit = rcvbuf_limit(sk, skb) + atomic_read(&tsk->dupl_rcvcnt);
- if (likely(!sk_add_backlog(sk, skb, limit)))
- skb = NULL;
- else
- err = -TIPC_ERR_OVERLOAD;
- }
+ err = tipc_sk_enqueue_skb(sk, &skb);
spin_unlock_bh(&sk->sk_lock.slock);
sock_put(sk);
exit:
--
1.9.1
------------------------------------------------------------------------------
Dive into the World of Parallel Programming. The Go Parallel Website,
sponsored by Intel and developed in partnership with Slashdot Media, is your
hub for all things parallel software development, from weekly thought
leadership blogs to news, videos, case studies, tutorials and more. Take a
look and join the conversation now. http://goparallel.sourceforge.net/
^ permalink raw reply related
* [PATCH net-next 4/9] tipc: split up function tipc_msg_eval()
From: Jon Maloy @ 2015-02-05 13:36 UTC (permalink / raw)
To: davem; +Cc: Jon Maloy, netdev, Paul Gortmaker, tipc-discussion
In-Reply-To: <1423143404-23322-1-git-send-email-jon.maloy@ericsson.com>
The function tipc_msg_eval() is in reality doing two related, but
different tasks. First it tries to find a new destination for named
messages, in case there was no first lookup, or if the first lookup
failed. Second, it does what its name suggests, evaluating the validity
of the message and its destination, and returning an appropriate error
code depending on the result.
This is confusing, and in this commit we choose to break it up into two
functions. A new function, tipc_msg_lookup_dest(), first attempts to find
a new destination, if the message is of the right type. If this lookup
fails, or if the message should not be subject to a second lookup, the
already existing tipc_msg_reverse() is called. This function performs
prepares the message for rejection, if applicable.
Reviewed-by: Ying Xue <ying.xue@windriver.com>
Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
---
net/tipc/msg.c | 42 +++++++++++++++++++++---------------------
net/tipc/msg.h | 9 +++++----
net/tipc/socket.c | 40 ++++++++++++++++++++++------------------
3 files changed, 48 insertions(+), 43 deletions(-)
diff --git a/net/tipc/msg.c b/net/tipc/msg.c
index 940d741..697223a 100644
--- a/net/tipc/msg.c
+++ b/net/tipc/msg.c
@@ -411,43 +411,43 @@ bool tipc_msg_reverse(u32 own_addr, struct sk_buff *buf, u32 *dnode,
return true;
exit:
kfree_skb(buf);
+ *dnode = 0;
return false;
}
/**
- * tipc_msg_eval: determine fate of message that found no destination
- * @buf: the buffer containing the message.
- * @dnode: return value: next-hop node, if message to be forwarded
- * @err: error code to use, if message to be rejected
- *
+ * tipc_msg_lookup_dest(): try to find new destination for named message
+ * @skb: the buffer containing the message.
+ * @dnode: return value: next-hop node, if destination found
+ * @err: return value: error code to use, if message to be rejected
* Does not consume buffer
- * Returns 0 (TIPC_OK) if message ok and we can try again, -TIPC error
- * code if message to be rejected
+ * Returns true if a destination is found, false otherwise
*/
-int tipc_msg_eval(struct net *net, struct sk_buff *buf, u32 *dnode)
+bool tipc_msg_lookup_dest(struct net *net, struct sk_buff *skb,
+ u32 *dnode, int *err)
{
- struct tipc_msg *msg = buf_msg(buf);
+ struct tipc_msg *msg = buf_msg(skb);
u32 dport;
- if (msg_type(msg) != TIPC_NAMED_MSG)
- return -TIPC_ERR_NO_PORT;
- if (skb_linearize(buf))
- return -TIPC_ERR_NO_NAME;
- if (msg_data_sz(msg) > MAX_FORWARD_SIZE)
- return -TIPC_ERR_NO_NAME;
+ if (!msg_isdata(msg))
+ return false;
+ if (!msg_named(msg))
+ return false;
+ *err = -TIPC_ERR_NO_NAME;
+ if (skb_linearize(skb))
+ return false;
if (msg_reroute_cnt(msg) > 0)
- return -TIPC_ERR_NO_NAME;
-
+ return false;
*dnode = addr_domain(net, msg_lookup_scope(msg));
dport = tipc_nametbl_translate(net, msg_nametype(msg),
- msg_nameinst(msg),
- dnode);
+ msg_nameinst(msg), dnode);
if (!dport)
- return -TIPC_ERR_NO_NAME;
+ return false;
msg_incr_reroute_cnt(msg);
msg_set_destnode(msg, *dnode);
msg_set_destport(msg, dport);
- return TIPC_OK;
+ *err = TIPC_OK;
+ return true;
}
/* tipc_msg_reassemble() - clone a buffer chain of fragments and
diff --git a/net/tipc/msg.h b/net/tipc/msg.h
index f7ea954..6070299 100644
--- a/net/tipc/msg.h
+++ b/net/tipc/msg.h
@@ -750,18 +750,19 @@ static inline u32 msg_tot_origport(struct tipc_msg *m)
struct sk_buff *tipc_buf_acquire(u32 size);
bool tipc_msg_reverse(u32 own_addr, struct sk_buff *buf, u32 *dnode,
int err);
-int tipc_msg_eval(struct net *net, struct sk_buff *buf, u32 *dnode);
void tipc_msg_init(u32 own_addr, struct tipc_msg *m, u32 user, u32 type,
u32 hsize, u32 destnode);
-struct sk_buff *tipc_msg_create(uint user, uint type,
- uint hdr_sz, uint data_sz, u32 dnode,
- u32 onode, u32 dport, u32 oport, int errcode);
+struct sk_buff *tipc_msg_create(uint user, uint type, uint hdr_sz,
+ uint data_sz, u32 dnode, u32 onode,
+ u32 dport, u32 oport, int errcode);
int tipc_buf_append(struct sk_buff **headbuf, struct sk_buff **buf);
bool tipc_msg_bundle(struct sk_buff_head *list, struct sk_buff *skb, u32 mtu);
bool tipc_msg_make_bundle(struct sk_buff_head *list,
struct sk_buff *skb, u32 mtu, u32 dnode);
int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m,
int offset, int dsz, int mtu, struct sk_buff_head *list);
+bool tipc_msg_lookup_dest(struct net *net, struct sk_buff *skb, u32 *dnode,
+ int *err);
struct sk_buff *tipc_msg_reassemble(struct sk_buff_head *list);
#endif
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 1d98bfc..e14b2ae 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -1739,7 +1739,7 @@ static int filter_rcv(struct sock *sk, struct sk_buff **skb)
* @sk: socket
* @skb: message
*
- * Caller must hold socket lock, but not port lock.
+ * Caller must hold socket lock
*
* Returns 0
*/
@@ -1805,27 +1805,31 @@ int tipc_sk_rcv(struct net *net, struct sk_buff *skb)
struct tipc_net *tn;
struct sock *sk;
u32 dport = msg_destport(buf_msg(skb));
- int err;
+ int err = -TIPC_ERR_NO_PORT;
u32 dnode;
- /* Validate destination and message */
+ /* Find destination */
tsk = tipc_sk_lookup(net, dport);
- if (unlikely(!tsk)) {
- err = tipc_msg_eval(net, skb, &dnode);
- goto exit;
- }
- sk = &tsk->sk;
-
- spin_lock_bh(&sk->sk_lock.slock);
- err = tipc_sk_enqueue_skb(sk, &skb);
- spin_unlock_bh(&sk->sk_lock.slock);
- sock_put(sk);
-exit:
- if (unlikely(skb)) {
- tn = net_generic(net, tipc_net_id);
- if (!err || tipc_msg_reverse(tn->own_addr, skb, &dnode, -err))
- tipc_link_xmit_skb(net, skb, dnode, 0);
+ if (likely(tsk)) {
+ sk = &tsk->sk;
+ spin_lock_bh(&sk->sk_lock.slock);
+ err = tipc_sk_enqueue_skb(sk, &skb);
+ spin_unlock_bh(&sk->sk_lock.slock);
+ sock_put(sk);
}
+ if (likely(!skb))
+ return 0;
+ if (tipc_msg_lookup_dest(net, skb, &dnode, &err))
+ goto xmit;
+ if (!err) {
+ dnode = msg_destnode(buf_msg(skb));
+ goto xmit;
+ }
+ tn = net_generic(net, tipc_net_id);
+ if (!tipc_msg_reverse(tn->own_addr, skb, &dnode, -err))
+ return -EHOSTUNREACH;
+xmit:
+ tipc_link_xmit_skb(net, skb, dnode, dport);
return err ? -EHOSTUNREACH : 0;
}
--
1.9.1
------------------------------------------------------------------------------
Dive into the World of Parallel Programming. The Go Parallel Website,
sponsored by Intel and developed in partnership with Slashdot Media, is your
hub for all things parallel software development, from weekly thought
leadership blogs to news, videos, case studies, tutorials and more. Take a
look and join the conversation now. http://goparallel.sourceforge.net/
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox