Netdev List
 help / color / mirror / Atom feed
* Re: [Bloat] Linux network is damn fast, need more use XDP (Was: DC behaviors today)
From: Dave Taht @ 2017-12-04 17:00 UTC (permalink / raw)
  To: Jesper Dangaard Brouer
  Cc: netdev@vger.kernel.org, Christina Jacob, Joel Wirāmu Pauling,
	cerowrt-devel@lists.bufferbloat.net, bloat, David Ahern,
	Tariq Toukan
In-Reply-To: <20171204110923.3a213986@redhat.com>

Jesper:

I have a tendency to deal with netdev by itself and never cross post
there, as the bufferbloat.net servers (primarily to combat spam)
mandate starttls and vger doesn't support it at all, thus leading to
raising davem blood pressure which I'd rather not do.

But moving on...

On Mon, Dec 4, 2017 at 2:56 AM, Jesper Dangaard Brouer
<brouer@redhat.com> wrote:
>
> On Sun, 03 Dec 2017 20:19:33 -0800 Dave Taht <dave@taht.net> wrote:
>
>> Changing the topic, adding bloat.
>
> Adding netdev, and also adjust the topic to be a rant on that the Linux
> kernel network stack is actually damn fast, and if you need something
> faster then XDP can solved your needs...
>
>> Joel Wirāmu Pauling <joel@aenertia.net> writes:
>>
>> > Just from a Telco/Industry perspective slant.
>> >
>> > Everything in DC has moved to SFP28 interfaces at 25Gbit as the server
>> > port of interconnect. Everything TOR wise is now QSFP28 - 100Gbit.
>> > Mellanox X5 cards are the current hotness, and their offload
>> > enhancements (ASAP2 - which is sorta like DPDK on steroids) allows for
>> > OVS flow rules programming into the card. We have a lot of customers
>> > chomping at the bit for that feature (disclaimer I work for Nuage
>> > Networks, and we are working on enhanced OVS to do just that) for NFV
>> > workloads.
>>
>> What Jesper's been working on for ages has been to try and get linux's
>> PPS up for small packets, which last I heard was hovering at about
>> 4Gbits.
>
> I hope you made a typo here Dave, the normal Linux kernel is definitely
> way beyond 4Gbit/s, you must have misunderstood something, maybe you
> meant 40Gbit/s? (which is also too low)

The context here was PPS for *non-gro'd* tcp ack packets, in the
further context of
the increasingly epic "benefits of ack filtering" thread on the bloat
list, in the context
that for 50x1 end-user-asymmetry we were seeing 90% less acks with the new
sch_cake ack-filter code, double the throughput...

The kind of return traffic you see from data sent outside the DC, with
tons of flows.

What's that number?

>
> Scaling up to more CPUs and TCP-stream, Tariq[1] and I have showed the
> Linux kernel network stack scales to 94Gbit/s (linerate minus overhead).
> But when the drivers page-recycler fails, we hit bottlenecks in the
> page-allocator, that cause negative scaling to around 43Gbit/s.

So I divide by 94/22 and get 4gbit for acks. Or I look at PPS * 66. Or?

> [1] http://lkml.kernel.org/r/cef85936-10b2-5d76-9f97-cb03b418fd94@mellanox.com
>
> Linux have for a _long_ time been doing 10Gbit/s TCP-stream easily, on
> a SINGLE CPU.  This is mostly thanks to TSO/GRO aggregating packets,
> but last couple of years the network stack have been optimized (with
> UDP workloads), and as a result we can do 10G without TSO/GRO on a
> single-CPU.  This is "only" 812Kpps with MTU size frames.

acks.

> It is important to NOTICE that I'm mostly talking about SINGLE-CPU
> performance.  But the Linux kernel scales very well to more CPUs, and
> you can scale this up, although we are starting to hit scalability
> issues in MM-land[1].
>
> I've also demonstrated that netdev-community have optimized the kernels
> per-CPU processing power to around 2Mpps.  What does this really
> mean... well with MTU size packets 812Kpps was 10Gbit/s, thus 25Gbit/s
> should be around 2Mpps.... That implies Linux can do 25Gbit/s on a
> single CPU without GRO (MTU size frames).  Do you need more I ask?

The benchmark I had in mind was, say, 100k flows going out over the internet,
and the characteristics of the ack flows on the return path.

>
>
>> The route table lookup also really expensive on the main cpu.

To clarify the context here, I was asking specifically if the X5 mellonox card
did routing table offlload or only switching.

> Well, it used-to-be very expensive. Vincent Bernat wrote some excellent
> blogposts[2][3] on the recent improvements over kernel versions, and
> gave due credit to people involved.
>
> [2] https://vincent.bernat.im/en/blog/2017-performance-progression-ipv4-route-lookup-linux
> [3] https://vincent.bernat.im/en/blog/2017-performance-progression-ipv6-route-lookup-linux
>
> He measured around 25 to 35 nanosec cost of route lookups.  My own
> recent measurements were 36.9 ns cost of fib_table_lookup.

On intel hw.

>
>> Does this stuff offload the route table lookup also?
>
> If you have not heard, the netdev-community have worked on something
> called XDP (eXpress Data Path).  This is a new layer in the network
> stack, that basically operates a the same "layer"/level as DPDK.
> Thus, surprise we get the same performance numbers as DPDK. E.g. I can
> do 13.4 Mpps forwarding with ixgbe on a single CPU (more CPUs=14.6Mps)
>
> We can actually use XDP for (software) offloading the Linux routing
> table.  There are two methods we are experimenting with:
>
> (1) externally monitor route changes from userspace and update BPF-maps
> to reflect this. That approach is already accepted upstream[4][5].  I'm
> measuring 9,513,746 pps per CPU with that approach.
>
> (2) add a bpf helper to simply call fib_table_lookup() from the XDP hook.
> This is still experimental patches (credit to David Ahern), and I've
> measured 9,350,160 pps with this approach in a single CPU.  Using more
> CPUs we hit 14.6Mpps (only used 3 CPUs in that test)

Neat. Perhaps trying xdp on the itty bitty routers I usually work on
would be a win.
quad arm cores are increasingy common there.

>
> [4] https://github.com/torvalds/linux/blob/master/samples/bpf/xdp_router_ipv4_user.c
> [5] https://github.com/torvalds/linux/blob/master/samples/bpf/xdp_router_ipv4_kern.c

thx very much for the update.

> --
> Best regards,
>   Jesper Dangaard Brouer
>   MSc.CS, Principal Kernel Engineer at Red Hat
>   LinkedIn: http://www.linkedin.com/in/brouer
> _______________________________________________
> Bloat mailing list
> Bloat@lists.bufferbloat.net
> https://lists.bufferbloat.net/listinfo/bloat



-- 

Dave Täht
CEO, TekLibre, LLC
http://www.teklibre.com
Tel: 1-669-226-2619
_______________________________________________
Cerowrt-devel mailing list
Cerowrt-devel@lists.bufferbloat.net
https://lists.bufferbloat.net/listinfo/cerowrt-devel

^ permalink raw reply

* Re: [PATCH next-next 0/4] rtnetlink: rework handler (un)registering
From: David Miller @ 2017-12-04 16:57 UTC (permalink / raw)
  To: fw; +Cc: netdev
In-Reply-To: <20171204165304.GC28667@breakpoint.cc>

From: Florian Westphal <fw@strlen.de>
Date: Mon, 4 Dec 2017 17:53:04 +0100

> The only difference is that theoretically some addrlabel rtnetlink
> ops are not available if registration fails, but thats not really worse
> than before as this used to panic() instead :-)
> 
> I can send a followup patch, to convert all of ipv6, should be easy
> to propagate errors from addrlabel initialisation to its callsite.

Yes, please make ipv6 consistent in this area when you get a chance.

Thanks.

^ permalink raw reply

* Re: [PATCH 1/2] net: sh_eth: add support for SH7786
From: Sergei Shtylyov @ 2017-12-04 16:56 UTC (permalink / raw)
  To: Thomas Petazzoni, David S. Miller, Niklas Söderlund,
	Geert Uytterhoeven, Simon Horman
  Cc: netdev, linux-renesas-soc
In-Reply-To: <20171204141744.18599-2-thomas.petazzoni@free-electrons.com>

On 12/04/2017 05:17 PM, Thomas Petazzoni wrote:

> This commit adds the sh_eth_cpu_data structure that describes the
> SH7786 variant of the IP.

    The manual seems to be unavailable, so I have to trust you. :-)

> Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>

Acked-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>

[...]

MBR, Sergei

^ permalink raw reply

* Re: [PATCH next-next 0/4] rtnetlink: rework handler (un)registering
From: Florian Westphal @ 2017-12-04 16:53 UTC (permalink / raw)
  To: David Miller; +Cc: fw, netdev
In-Reply-To: <20171204.113401.1266159215993063523.davem@davemloft.net>

David Miller <davem@davemloft.net> wrote:
> From: Florian Westphal <fw@strlen.de>
> Date: Sat,  2 Dec 2017 21:44:04 +0100
> 
> > Peter Zijlstra reported (referring to commit 019a316992ee0d983,
> > "rtnetlink: add reference counting to prevent module unload while dump is in progress"):
> > 
> >  1) it not in fact a refcount, so using refcount_t is silly
> >  2) there is a distinct lack of memory barriers, so we can easily
> >     observe the decrement while the msg_handler is still in progress.
> >  3) waiting with a schedule()/yield() loop is complete crap and subject
> >     life-locks, imagine doing that rtnl_unregister_all() from a RT task.
> > 
> > In ancient times rtnetlink exposed a statically-sized table with
> > preset doit/dumpit handlers to be called for a protocol/type pair.
> > 
> > Later the rtnl_register interface was added and the table was allocated
> > on demand.  Eventually these were also used by modules.
> > 
> > Problem is that nothing prevents module unload while a netlink dump
> > is in progress.  netlink dumps can be span multiple recv calls and
> > netlink core saves the to-be-repeated dumper address for later invocation.
> > 
> > To prevent rmmod the netlink core expects callers to pass in the owning
> > module so a reference can be taken.
> > 
> > So far rtnetlink wasn't doing this, add new interface to pass THIS_MODULE.
> > Moreover, when converting parts of the rtnetlink handling to rcu this code
> > gained way too many READ_ONCE spots, remove them and the extra refcounting.
> > 
> > Take a module reference when running dumpit and doit callbacks
> > and never alter content of rtnl_link structures after they have been
> > published via rcu_assign_pointer.
> > 
> > Based partially on earlier patch from Peter.
> 
> Series applied, thanks Florian.
> 
> BTW, why did you use rtnl_register_module() for most of ipv6 but
> specifically not for the net/ipv6/addrconf.c stuff?

Right, originally I did not convert ipv6 at all, as even if its
a module it cannot be unloaded.

Then I thought it might be good to also get rid of of panic() in
rtnl_register (which made __rtnl_register redundant).

I switched to _module() where error handling wasn't too hard
(i.e., where we can make module insertion fail without adding too many
 error unwinding stunts).

The only difference is that theoretically some addrlabel rtnetlink
ops are not available if registration fails, but thats not really worse
than before as this used to panic() instead :-)

I can send a followup patch, to convert all of ipv6, should be easy
to propagate errors from addrlabel initialisation to its callsite.

^ permalink raw reply

* pull-request: ieee802154-next 2017-12-04
From: Stefan Schmidt @ 2017-12-04 16:51 UTC (permalink / raw)
  To: davem; +Cc: linux-wpan, alex.aring, netdev

Hello Dave.

Some update from ieee802154 to *net-next*

Jian-Hong Pan updated our docs to match the APIs in code.
Michael Hennerichs enhanced the adf7242 driver to work with adf7241
devices and reworked the IRQ and packet handling in the driver.


The following changes since commit 1d3b78bbc6e983fabb3fbf91b76339bf66e4a12c:

  Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net (2017-11-23 21:18:46 -1000)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/sschmidt/wpan-next.git ieee802154-for-davem-2017-12-04

for you to fetch changes up to 8f1878a182dcc5a15a57c7fc7d8182bea0733dfa:

  net: ieee802154: adf7242: Rework IRQ and packet handling (2017-11-29 16:49:41 +0100)

----------------------------------------------------------------
Jian-Hong Pan (1):
      doc: linux-wpan: Fulfill the description of missed 802.15.4 APIs

Michael Hennerich (5):
      net: ieee802154: adf7242: Add support for ADF7241 devices
      net: ieee802154: adf7242: Fix bug if defined DEBUG
      net: ieee802154: adf7242: Add additional DEBUG information
      net: ieee802154: adf7242: Avoid redundant RC_READY polling
      net: ieee802154: adf7242: Rework IRQ and packet handling

 .../devicetree/bindings/net/ieee802154/adf7242.txt |  2 +-
 Documentation/networking/ieee802154.txt            | 40 ++++++++++
 drivers/net/ieee802154/adf7242.c                   | 90 +++++++++++++++-------
 3 files changed, 105 insertions(+), 27 deletions(-)


regards
Stefan Schmidt

^ permalink raw reply

* Re: [PATCH net-next 1/4] net: Introduce NETIF_F_GRO_HW
From: Alexander Duyck @ 2017-12-04 16:47 UTC (permalink / raw)
  To: Michael Chan; +Cc: David Miller, Netdev, Ariel Elior, everest-linux-l2
In-Reply-To: <1512385967-32339-2-git-send-email-michael.chan@broadcom.com>

On Mon, Dec 4, 2017 at 3:12 AM, Michael Chan <michael.chan@broadcom.com> wrote:
> Introduce NETIF_F_GRO_HW feature flag for NICs that support hardware
> GRO.  With this flag, we can now independently turn on or off hardware
> GRO when GRO is on.  Hardware GRO guarantees that packets can be
> re-segmented by TSO/GSO to reconstruct the original packet stream.
>
> Cc: Ariel Elior <Ariel.Elior@cavium.com>
> Cc: everest-linux-l2@cavium.com
> Signed-off-by: Michael Chan <michael.chan@broadcom.com>

Do we really need yet another feature bit for this? We already have
LRO and GRO and now we have to add something that isn't quite either
one?

I think I would rather have something like a netdev private flag that
says LRO assembled frames are routable and just have this all run over
the LRO flag with a test for the private flag to avoid triggering the
LRO disable in the case of the flag being present. Really this is just
a clean LRO implementation anyway so maybe we should just go that
route where LRO is the hardware offload and GRO is the generic
software implementation of that offload. That way when GRO gets some
new feature that your hardware doesn't support we don't have to argue
about the differences since LRO is meant to be a limited
implementation anyway due to the nature of it being in hardware.

To me it just seems like this is an attempt to use the GRO name as a
marketing term and I really don't like the feel of it.

> ---
>  Documentation/networking/netdev-features.txt |  7 +++++++
>  include/linux/netdev_features.h              |  5 ++++-
>  net/core/dev.c                               | 13 +++++++++++++
>  net/core/ethtool.c                           |  1 +
>  4 files changed, 25 insertions(+), 1 deletion(-)
>
> diff --git a/Documentation/networking/netdev-features.txt b/Documentation/networking/netdev-features.txt
> index 7413eb0..d76d332 100644
> --- a/Documentation/networking/netdev-features.txt
> +++ b/Documentation/networking/netdev-features.txt
> @@ -163,3 +163,10 @@ This requests that the NIC receive all possible frames, including errored
>  frames (such as bad FCS, etc).  This can be helpful when sniffing a link with
>  bad packets on it.  Some NICs may receive more packets if also put into normal
>  PROMISC mode.
> +
> +*  rx-gro-hw
> +
> +This requests that the NIC enables Hardware GRO (generic receive offload).
> +Hardware GRO is basically the exact reverse of TSO, and is generally
> +stricter than Hardware LRO.  A packet stream merged by Hardware GRO must
> +be re-segmentable by GSO or TSO back to the exact packet stream.
> diff --git a/include/linux/netdev_features.h b/include/linux/netdev_features.h
> index dc8b489..d18ef6f 100644
> --- a/include/linux/netdev_features.h
> +++ b/include/linux/netdev_features.h
> @@ -77,6 +77,8 @@ enum {
>         NETIF_F_HW_ESP_TX_CSUM_BIT,     /* ESP with TX checksum offload */
>         NETIF_F_RX_UDP_TUNNEL_PORT_BIT, /* Offload of RX port for UDP tunnels */
>
> +       NETIF_F_GRO_HW_BIT,             /* Hardware Generic receive offload */
> +
>         /*
>          * Add your fresh new feature above and remember to update
>          * netdev_features_strings[] in net/core/ethtool.c and maybe
> @@ -96,6 +98,7 @@ enum {
>  #define NETIF_F_FRAGLIST       __NETIF_F(FRAGLIST)
>  #define NETIF_F_FSO            __NETIF_F(FSO)
>  #define NETIF_F_GRO            __NETIF_F(GRO)
> +#define NETIF_F_GRO_HW         __NETIF_F(GRO_HW)
>  #define NETIF_F_GSO            __NETIF_F(GSO)
>  #define NETIF_F_GSO_ROBUST     __NETIF_F(GSO_ROBUST)
>  #define NETIF_F_HIGHDMA                __NETIF_F(HIGHDMA)
> @@ -193,7 +196,7 @@ enum {
>   * If upper/master device has these features disabled, they must be disabled
>   * on all lower/slave devices as well.
>   */
> -#define NETIF_F_UPPER_DISABLES NETIF_F_LRO
> +#define NETIF_F_UPPER_DISABLES (NETIF_F_LRO | NETIF_F_GRO_HW)
>
>  /* changeable features with no special hardware requirements */
>  #define NETIF_F_SOFT_FEATURES  (NETIF_F_GSO | NETIF_F_GRO)
> diff --git a/net/core/dev.c b/net/core/dev.c
> index 30b5fe3..09c2ad0 100644
> --- a/net/core/dev.c
> +++ b/net/core/dev.c
> @@ -7392,6 +7392,19 @@ static netdev_features_t netdev_fix_features(struct net_device *dev,
>                 features &= ~dev->gso_partial_features;
>         }
>
> +       if (features & NETIF_F_GRO_HW) {
> +               /* Hardware GRO depends on GRO. */
> +               if (!(features & NETIF_F_GRO)) {
> +                       netdev_dbg(dev, "Dropping NETIF_F_GSO_HW since no GRO feature.\n");
> +                       features &= ~NETIF_F_GRO_HW;
> +               }
> +               /* Hardware GRO and LRO are mutually exclusive. */
> +               if (features & NETIF_F_LRO) {
> +                       netdev_dbg(dev, "Dropping NETIF_F_LRO since GRO_HW is set.\n");
> +                       features &= ~NETIF_F_LRO;
> +               }
> +       }
> +
>         return features;
>  }
>
> diff --git a/net/core/ethtool.c b/net/core/ethtool.c
> index f8fcf45..50a7920 100644
> --- a/net/core/ethtool.c
> +++ b/net/core/ethtool.c
> @@ -73,6 +73,7 @@ int ethtool_op_get_ts_info(struct net_device *dev, struct ethtool_ts_info *info)
>         [NETIF_F_LLTX_BIT] =             "tx-lockless",
>         [NETIF_F_NETNS_LOCAL_BIT] =      "netns-local",
>         [NETIF_F_GRO_BIT] =              "rx-gro",
> +       [NETIF_F_GRO_HW_BIT] =           "rx-gro-hw",
>         [NETIF_F_LRO_BIT] =              "rx-lro",
>
>         [NETIF_F_TSO_BIT] =              "tx-tcp-segmentation",
> --
> 1.8.3.1
>

^ permalink raw reply

* Re: [bisected] x86 boot still broken on -rc2
From: Prarit Bhargava @ 2017-12-04 16:45 UTC (permalink / raw)
  To: linux-kernel
  Cc: Prarit Bhargava, Prarit, Jakub Kicinski, netdev@vger.kernel.org,
	Thomas Gleixner, Clark Williams
In-Reply-To: <b7e29d24-2317-2355-65aa-04978bd45add@redhat.com>

On 12/04/2017 08:13 AM, Prarit Bhargava wrote:
> 
> 
> x86: Booting SMP configuration:
> .... node  #0, CPUs:        #1  #2  #3  #4
> .... node  #1, CPUs:    #5  #6  #7  #8  #9
> .... node  #0, CPUs:   #10 #11 #12 #13 #14
> .... node  #1, CPUs:   #15 #16 #17 #18 #19
> smp: Brought up 2 nodes, 20 CPUs
> smpboot: Max logical packages: 1
> 
> which means that the calculation of logical packages is wrong because
> 
>       ncpus = cpu_data(0).booted_cores * smp_num_siblings;
>       ncpus = 10 * 2;
>       ncpus = 20;
> 
> smp_num_siblings is defined as "The number of threads in a core" which
> should be 1 if HT/SMT is disabled.
> 
> It looks like my patch has exposed a bug in the
> smp_num_siblings calculation.   I'm still debugging ...

The bug is that smp_num_siblings has been incorrectly calculated as the
*maximum* number of threads in a core, and not the actual number of threads in
a core on systems which have a CPUID level greater than 0xb.  (see
arch/x86/kernel/cpu/topology.c:59)

That will take some time to investigate and come up with a proper solution and
fix.  In the meantime, the patch below will fix the problem in the short-term.
I've tested the patch using SMT enabled, SMT disabled, maxcpus=1 and nr_cpus=1.

tglx, Please revert b4c0a7326f5d ("x86/smpboot: Fix __max_logical_packages
estimate") if you think that is a better option.  The problem with
smp_num_siblings has been around for almost a decade.

P.

---8<---

Subject: [PATCH] arch/x86: Do not use smp_num_siblings in
 __max_logical_packages calculation

Documentation/x86/topology.txt defines smp_num_siblings as "The number of
threads in a core".  Since commit bbb65d2d365e ("x86: use cpuid vector 0xb
when available for detecting cpu topology") smp_num_siblings is the
maximum number of threads in a core.  If Simultaneous MultiThreading
(SMT) is disabled on a system, smp_num_siblings is 2 and not 1 as
expected.

Use topology_max_smt_threads() in the __max_logical_packages calculation.

Signed-off-by: Prarit Bhargava <prarit@redhat.com
Cc: Jakub Kicinski <kubakici@wp.pl>
Cc: "netdev@vger.kernel.org" <netdev@vger.kernel.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Clark Williams <williams@redhat.com>
---
 arch/x86/kernel/smpboot.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 3d01df7d7cf6..eaee15fb7d8b 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -1304,7 +1304,7 @@ void __init native_smp_cpus_done(unsigned int max_cpus)
 	 * Today neither Intel nor AMD support heterogenous systems so
 	 * extrapolate the boot cpu's data to all packages.
 	 */
-	ncpus = cpu_data(0).booted_cores * smp_num_siblings;
+	ncpus = cpu_data(0).booted_cores * topology_max_smt_threads();
 	__max_logical_packages = DIV_ROUND_UP(nr_cpu_ids, ncpus);
 	pr_info("Max logical packages: %u\n", __max_logical_packages);
 
-- 
1.8.3.1

^ permalink raw reply related

* Re: [PATCH 03/10] net: ezchip: nps_enet: Fix platform_get_irq's error checking
From: arvindY @ 2017-12-04 16:44 UTC (permalink / raw)
  To: Russell King - ARM Linux, David Miller
  Cc: f.fainelli, netdev, michal.simek, linux-kernel, opendmb, mkl,
	linux-arm-kernel, Vladislav.Zakharov, wg
In-Reply-To: <20171204164224.GU10595@n2100.armlinux.org.uk>



On Monday 04 December 2017 10:12 PM, Russell King - ARM Linux wrote:
> On Mon, Dec 04, 2017 at 11:34:48AM -0500, David Miller wrote:
>> From: Russell King - ARM Linux <linux@armlinux.org.uk>
>> Date: Mon, 4 Dec 2017 16:24:47 +0000
>>
>>> On Mon, Dec 04, 2017 at 11:20:49AM -0500, David Miller wrote:
>>>> From: Arvind Yadav <arvind.yadav.cs@gmail.com>
>>>> Date: Sun,  3 Dec 2017 00:56:15 +0530
>>>>
>>>>> The platform_get_irq() function returns negative if an error occurs.
>>>>> zero or positive number on success. platform_get_irq() error checking
>>>>> for zero is not correct. And remove unnecessary check for free_netdev().
>>>>>
>>>>> Signed-off-by: Arvind Yadav <arvind.yadav.cs@gmail.com>
>>>>> ---
>>>>>   drivers/net/ethernet/ezchip/nps_enet.c | 7 +++----
>>>>>   1 file changed, 3 insertions(+), 4 deletions(-)
>>>>>
>>>>> diff --git a/drivers/net/ethernet/ezchip/nps_enet.c b/drivers/net/ethernet/ezchip/nps_enet.c
>>>>> index 659f1ad..82dc6d0 100644
>>>>> --- a/drivers/net/ethernet/ezchip/nps_enet.c
>>>>> +++ b/drivers/net/ethernet/ezchip/nps_enet.c
>>>>> @@ -623,9 +623,9 @@ static s32 nps_enet_probe(struct platform_device *pdev)
>>>>>   
>>>>>   	/* Get IRQ number */
>>>>>   	priv->irq = platform_get_irq(pdev, 0);
>>>>> -	if (!priv->irq) {
>>>>> +	if (priv->irq <= 0) {
>>>>>   		dev_err(dev, "failed to retrieve <irq Rx-Tx> value from device tree\n");
>>>>> -		err = -ENODEV;
>>>>> +		err = priv->irq ? priv->irq : -ENODEV;
>>>> If platform_get_irq() returns "zero or positive number on success" then this
>>>> test is wrong and should be "if (priv->irq < 0)"
>>>>
>>>> Also, this series is a mix of different kinds of changes.
>>>>
>>>> Please separate out the platform IRQ error checking and just submit exactly
>>>> those changes as a patch series.
>>>>
>>>> The other bug fixes should be submitted outside of those changes since they
>>>> are unrelated.
>>> The issue of whether IRQ 0 is valid or not has been covered several times
>>> by Linus, and the result is that it is deemed by Linus that IRQ 0 is not
>>> a valid interrupt.
>> Then either platform_get_irq() as defined or this commit message (or both)
>> are wrong.
> Indeed, the commit message is wrong, and that's already been pointed out
> in previous patch sets.
>
I will change commit message.  Commit message will be
  " The platform_get_irq() function returns negative if an
error occurs, Zero if No irq found and positive number
on get irq successful. platform_get_irq() error checking for
only zero is not correct."

^ permalink raw reply

* Re: [PATCH 03/10] net: ezchip: nps_enet: Fix platform_get_irq's error checking
From: Russell King - ARM Linux @ 2017-12-04 16:42 UTC (permalink / raw)
  To: David Miller
  Cc: arvind.yadav.cs, f.fainelli, netdev, michal.simek, linux-kernel,
	opendmb, mkl, linux-arm-kernel, Vladislav.Zakharov, wg
In-Reply-To: <20171204.113448.651799079717687661.davem@davemloft.net>

On Mon, Dec 04, 2017 at 11:34:48AM -0500, David Miller wrote:
> From: Russell King - ARM Linux <linux@armlinux.org.uk>
> Date: Mon, 4 Dec 2017 16:24:47 +0000
> 
> > On Mon, Dec 04, 2017 at 11:20:49AM -0500, David Miller wrote:
> >> From: Arvind Yadav <arvind.yadav.cs@gmail.com>
> >> Date: Sun,  3 Dec 2017 00:56:15 +0530
> >> 
> >> > The platform_get_irq() function returns negative if an error occurs.
> >> > zero or positive number on success. platform_get_irq() error checking
> >> > for zero is not correct. And remove unnecessary check for free_netdev().
> >> > 
> >> > Signed-off-by: Arvind Yadav <arvind.yadav.cs@gmail.com>
> >> > ---
> >> >  drivers/net/ethernet/ezchip/nps_enet.c | 7 +++----
> >> >  1 file changed, 3 insertions(+), 4 deletions(-)
> >> > 
> >> > diff --git a/drivers/net/ethernet/ezchip/nps_enet.c b/drivers/net/ethernet/ezchip/nps_enet.c
> >> > index 659f1ad..82dc6d0 100644
> >> > --- a/drivers/net/ethernet/ezchip/nps_enet.c
> >> > +++ b/drivers/net/ethernet/ezchip/nps_enet.c
> >> > @@ -623,9 +623,9 @@ static s32 nps_enet_probe(struct platform_device *pdev)
> >> >  
> >> >  	/* Get IRQ number */
> >> >  	priv->irq = platform_get_irq(pdev, 0);
> >> > -	if (!priv->irq) {
> >> > +	if (priv->irq <= 0) {
> >> >  		dev_err(dev, "failed to retrieve <irq Rx-Tx> value from device tree\n");
> >> > -		err = -ENODEV;
> >> > +		err = priv->irq ? priv->irq : -ENODEV;
> >> 
> >> If platform_get_irq() returns "zero or positive number on success" then this
> >> test is wrong and should be "if (priv->irq < 0)"
> >> 
> >> Also, this series is a mix of different kinds of changes.
> >> 
> >> Please separate out the platform IRQ error checking and just submit exactly
> >> those changes as a patch series.
> >> 
> >> The other bug fixes should be submitted outside of those changes since they
> >> are unrelated.
> > 
> > The issue of whether IRQ 0 is valid or not has been covered several times
> > by Linus, and the result is that it is deemed by Linus that IRQ 0 is not
> > a valid interrupt.
> 
> Then either platform_get_irq() as defined or this commit message (or both)
> are wrong.

Indeed, the commit message is wrong, and that's already been pointed out
in previous patch sets.

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line in suburbia: sync at 8.8Mbps down 630kbps up
According to speedtest.net: 8.21Mbps down 510kbps up

^ permalink raw reply

* Re: [RFC][PATCHES] sock_alloc_file() cleanups and fixes
From: Al Viro @ 2017-12-04 16:41 UTC (permalink / raw)
  To: David Miller; +Cc: netdev
In-Reply-To: <20171204.103524.186631681746357000.davem@davemloft.net>

On Mon, Dec 04, 2017 at 10:35:24AM -0500, David Miller wrote:
> From: Al Viro <viro@ZenIV.linux.org.uk>
> Date: Fri, 1 Dec 2017 00:20:27 +0000
> 
> > 	1) massage sys_socketpair() (should be a pure cleanup)
> > 	2) fix and clean up kcm_clone() (-stable fodder)
> > 	3) switch sock_alloc_file() to new calling conventions.
> > 
> > 	It got some local testing, but it certainly needs more review.
> > Diffstat for the entire thing is
> 
> Series looks great to me:
> 
> Acked-by: David S. Miller <davem@davemloft.net>

How do you prefer it to be handled?  KCM one should go into everything
since 4.6 (with trivial modifications in 4.11 and 4.12 - both had
massaged the place around the call of kcm_clone() a bit, but this fix
overwrites the entire area and that can be dropped into earlier
kernels without any problems).  I've put that into vfs.git#net-fixes
and have the other two in vfs.git#for-davem on top of that, with
you merging the latter into net-next.git and the former - into net.git.
Is that OK with you, or would you prefer some other way of handling
that kind of stuff?

^ permalink raw reply

* Re: [PATCH 2/2] net: sh_eth: make work on big endian systems
From: Sergei Shtylyov @ 2017-12-04 16:39 UTC (permalink / raw)
  To: Thomas Petazzoni, David S. Miller, Niklas Söderlund,
	Geert Uytterhoeven, Simon Horman
  Cc: netdev, linux-renesas-soc
In-Reply-To: <20171204141744.18599-3-thomas.petazzoni@free-electrons.com>

On 12/04/2017 05:17 PM, Thomas Petazzoni wrote:

> The sh_eth driver uses cpu_to_le32() and le32_to_cpu() to manipulate the
> fields of the DMA descriptors, making the assumption that the DMA 
> descriptors are little-endian.
> 
> However, testing on the Renesas SH7786 running in big-endian mode reveals
> that the DMA descriptors are also big-endian when running big-endian.
> Therefore, all the endianness conversion needs to be removed for the sh_eth
> driver to work.
> 
> Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> --- 
> Note: I see that Sergei Shtylyov has done some work around endianness on
> this driver back in 2015. I am not sure if it's used on other non-SuperH
> platforms in platforms where the CPU might run big-endian but the IP still
> be little-endian.

   The original Renesas' code assumed that... but the big-endian descriptors
(marked as such) were never used by the arch/sh/ code (and the code wouldn't
work right even if they did!). Therefore I did remove EDMAC_BIG_ENDIAN (and
now EDMAC_LITTLE_ENDIAN can be removed as well).

> If this is the case, then we would need a different approach and more
> discussion.

    No, the ARM platforms sh_eth is used on (mostly R-Car) seem to be
little-endian only.

> Therefore, it would be useful to wait for an ACK from Sergei before 
> applying this patch.
    You have it (-:

Acked-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>

MBR, Sergei

^ permalink raw reply

* [PATCH 3/3] dma-mapping: replace PCI_DMA_BUS_IS_PHYS with a flag in struct dma_map_ops
From: Christoph Hellwig @ 2017-12-04 16:36 UTC (permalink / raw)
  To: iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	linux-arch-u79uwXL29TY76Z2rM5mHXA,
	linux-block-u79uwXL29TY76Z2rM5mHXA, netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
  Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20171204163601.3055-1-hch-jcswGhMUV9g@public.gmane.org>

The current PCI_DMA_BUS_IS_PHYS decided if a dma implementation is bound
by the dma mask in the device because it directly maps to a physical
address range (modulo an offset in the device), or if it is virtualized
by an iommu and can map any address (that includes virtual iommus like
swiotlb).  The problem with this scheme is that it is per-architecture and
not per dma_ops instance, and we are growing more and more setups that
have multiple different dma operations in use on a single system, for
which this scheme can't provide a correct answer.  Depending on the
architecture that means we either get a false positive or false negative
at the moment.

This patch instead adds a new is_iommu flag in struct dma_map_ops that
tells if a dma_map_ops instance can map any possible physical address
to replace both the PCI_DMA_BUS_IS_PHYS macro and the is_phys field
in struct dma_map_ops used by it on a few architectures.

Note that this means that we now need a struct device parent in the
Scsi_Host or netdevice.  Every modern driver has these, but there might
still be a few outdated legacy drivers out there, which now won't make
an intelligent decision.

Signed-off-by: Christoph Hellwig <hch-jcswGhMUV9g@public.gmane.org>
---
 arch/alpha/include/asm/pci.h             |  5 -----
 arch/alpha/kernel/pci_iommu.c            |  1 +
 arch/arc/include/asm/pci.h               |  6 ------
 arch/arm/include/asm/pci.h               |  7 -------
 arch/arm64/include/asm/pci.h             |  5 -----
 arch/arm64/mm/dma-mapping.c              |  2 ++
 arch/cris/include/asm/pci.h              |  6 ------
 arch/h8300/include/asm/pci.h             |  2 --
 arch/hexagon/kernel/dma.c                |  1 -
 arch/ia64/hp/common/sba_iommu.c          |  4 +---
 arch/ia64/include/asm/pci.h              | 17 -----------------
 arch/ia64/kernel/pci-swiotlb.c           |  1 +
 arch/ia64/kernel/setup.c                 | 12 ------------
 arch/ia64/sn/kernel/io_common.c          |  5 -----
 arch/ia64/sn/pci/pci_dma.c               |  1 +
 arch/m68k/include/asm/pci.h              |  6 ------
 arch/microblaze/include/asm/pci.h        |  6 ------
 arch/mips/include/asm/pci.h              |  7 -------
 arch/mn10300/include/asm/pci.h           |  6 ------
 arch/parisc/include/asm/pci.h            | 23 -----------------------
 arch/parisc/kernel/setup.c               |  5 -----
 arch/powerpc/include/asm/pci.h           | 18 ------------------
 arch/powerpc/kernel/dma-iommu.c          |  1 +
 arch/powerpc/kernel/dma-swiotlb.c        |  1 +
 arch/powerpc/platforms/cell/iommu.c      |  1 +
 arch/powerpc/platforms/ps3/system-bus.c  |  2 ++
 arch/powerpc/platforms/pseries/ibmebus.c |  1 +
 arch/powerpc/platforms/pseries/vio.c     |  1 +
 arch/riscv/include/asm/pci.h             |  3 ---
 arch/s390/include/asm/pci.h              |  2 --
 arch/s390/pci/pci_dma.c                  |  3 +--
 arch/sh/include/asm/pci.h                |  6 ------
 arch/sh/kernel/dma-nommu.c               |  1 -
 arch/sparc/include/asm/pci_32.h          |  4 ----
 arch/sparc/include/asm/pci_64.h          |  6 ------
 arch/sparc/kernel/iommu.c                |  1 +
 arch/sparc/kernel/ioport.c               |  1 +
 arch/sparc/kernel/pci_sun4v.c            |  1 +
 arch/tile/include/asm/pci.h              | 14 --------------
 arch/tile/kernel/pci-dma.c               |  2 ++
 arch/x86/include/asm/pci.h               |  2 --
 arch/x86/kernel/amd_gart_64.c            |  1 +
 arch/x86/kernel/pci-calgary_64.c         |  1 +
 arch/x86/kernel/pci-nommu.c              |  1 -
 arch/x86/kernel/pci-swiotlb.c            |  1 +
 arch/x86/mm/mem_encrypt.c                |  1 +
 arch/x86/pci/sta2x11-fixup.c             |  1 +
 arch/xtensa/include/asm/pci.h            |  7 -------
 drivers/ide/ide-lib.c                    |  5 ++---
 drivers/ide/ide-probe.c                  |  2 +-
 drivers/iommu/amd_iommu.c                |  1 +
 drivers/iommu/intel-iommu.c              |  1 +
 drivers/parisc/ccio-dma.c                |  3 +--
 drivers/parisc/sba_iommu.c               |  3 +--
 drivers/pci/host/vmd.c                   |  1 +
 drivers/scsi/scsi_lib.c                  | 14 ++++++--------
 drivers/xen/swiotlb-xen.c                |  1 +
 include/asm-generic/pci.h                |  8 --------
 include/linux/dma-mapping.h              | 16 +++++++++++++++-
 lib/dma-virt.c                           |  1 +
 net/core/dev.c                           | 18 ++++++++----------
 tools/virtio/linux/dma-mapping.h         |  2 --
 62 files changed, 63 insertions(+), 225 deletions(-)

diff --git a/arch/alpha/include/asm/pci.h b/arch/alpha/include/asm/pci.h
index b9ec55351924..cf6bc1e64d66 100644
--- a/arch/alpha/include/asm/pci.h
+++ b/arch/alpha/include/asm/pci.h
@@ -56,11 +56,6 @@ struct pci_controller {
 
 /* IOMMU controls.  */
 
-/* The PCI address space does not equal the physical memory address space.
-   The networking and block device layers use this boolean for bounce buffer
-   decisions.  */
-#define PCI_DMA_BUS_IS_PHYS  0
-
 /* TODO: integrate with include/asm-generic/pci.h ? */
 static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
 {
diff --git a/arch/alpha/kernel/pci_iommu.c b/arch/alpha/kernel/pci_iommu.c
index 83b34b9188ea..bf83937d5368 100644
--- a/arch/alpha/kernel/pci_iommu.c
+++ b/arch/alpha/kernel/pci_iommu.c
@@ -949,6 +949,7 @@ const struct dma_map_ops alpha_pci_ops = {
 	.unmap_sg		= alpha_pci_unmap_sg,
 	.mapping_error		= alpha_pci_mapping_error,
 	.dma_supported		= alpha_pci_supported,
+	.is_iommu		= true,
 };
 
 const struct dma_map_ops *dma_ops = &alpha_pci_ops;
diff --git a/arch/arc/include/asm/pci.h b/arch/arc/include/asm/pci.h
index ba56c23c1b20..4ff53c041c64 100644
--- a/arch/arc/include/asm/pci.h
+++ b/arch/arc/include/asm/pci.h
@@ -16,12 +16,6 @@
 #define PCIBIOS_MIN_MEM 0x100000
 
 #define pcibios_assign_all_busses()	1
-/*
- * The PCI address space does equal the physical memory address space.
- * The networking and block device layers use this boolean for bounce
- * buffer decisions.
- */
-#define PCI_DMA_BUS_IS_PHYS	1
 
 #endif /* __KERNEL__ */
 
diff --git a/arch/arm/include/asm/pci.h b/arch/arm/include/asm/pci.h
index 960d9dc4f380..05b2eb2dc76f 100644
--- a/arch/arm/include/asm/pci.h
+++ b/arch/arm/include/asm/pci.h
@@ -22,13 +22,6 @@ static inline int pci_proc_domain(struct pci_bus *bus)
 }
 #endif /* CONFIG_PCI_DOMAINS */
 
-/*
- * The PCI address space does equal the physical memory address space.
- * The networking and block device layers use this boolean for bounce
- * buffer decisions.
- */
-#define PCI_DMA_BUS_IS_PHYS     (1)
-
 #define HAVE_PCI_MMAP
 #define ARCH_GENERIC_PCI_MMAP_RESOURCE
 
diff --git a/arch/arm64/include/asm/pci.h b/arch/arm64/include/asm/pci.h
index 8747f7c5e0e7..9e690686e8aa 100644
--- a/arch/arm64/include/asm/pci.h
+++ b/arch/arm64/include/asm/pci.h
@@ -18,11 +18,6 @@
 #define pcibios_assign_all_busses() \
 	(pci_has_flag(PCI_REASSIGN_ALL_BUS))
 
-/*
- * PCI address space differs from physical memory address space
- */
-#define PCI_DMA_BUS_IS_PHYS	(0)
-
 #define ARCH_GENERIC_PCI_MMAP_RESOURCE	1
 
 extern int isa_dma_bridge_buggy;
diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
index b45c5bcaeccb..43190a914c95 100644
--- a/arch/arm64/mm/dma-mapping.c
+++ b/arch/arm64/mm/dma-mapping.c
@@ -383,6 +383,7 @@ static const struct dma_map_ops swiotlb_dma_ops = {
 	.sync_sg_for_device = __swiotlb_sync_sg_for_device,
 	.dma_supported = __swiotlb_dma_supported,
 	.mapping_error = __swiotlb_dma_mapping_error,
+	.is_iommu = true,
 };
 
 static int __init atomic_pool_init(void)
@@ -867,6 +868,7 @@ static const struct dma_map_ops iommu_dma_ops = {
 	.map_resource = iommu_dma_map_resource,
 	.unmap_resource = iommu_dma_unmap_resource,
 	.mapping_error = iommu_dma_mapping_error,
+	.is_iommu = true,
 };
 
 static int __init __iommu_dma_init(void)
diff --git a/arch/cris/include/asm/pci.h b/arch/cris/include/asm/pci.h
index dcfef6407ae6..eb1f7f172f4b 100644
--- a/arch/cris/include/asm/pci.h
+++ b/arch/cris/include/asm/pci.h
@@ -27,12 +27,6 @@
 #include <linux/string.h>
 #include <asm/io.h>
 
-/* The PCI address space does equal the physical memory
- * address space.  The networking and block device layers use
- * this boolean for bounce buffer decisions.
- */
-#define PCI_DMA_BUS_IS_PHYS	(1)
-
 #define HAVE_PCI_MMAP
 #define ARCH_GENERIC_PCI_MMAP_RESOURCE
 
diff --git a/arch/h8300/include/asm/pci.h b/arch/h8300/include/asm/pci.h
index 7c9e55d62215..d4d345a52092 100644
--- a/arch/h8300/include/asm/pci.h
+++ b/arch/h8300/include/asm/pci.h
@@ -15,6 +15,4 @@ static inline void pcibios_penalize_isa_irq(int irq, int active)
 	/* We don't do dynamic PCI IRQ allocation */
 }
 
-#define PCI_DMA_BUS_IS_PHYS	(1)
-
 #endif /* _ASM_H8300_PCI_H */
diff --git a/arch/hexagon/kernel/dma.c b/arch/hexagon/kernel/dma.c
index 546792d176a4..35aaab72ddd0 100644
--- a/arch/hexagon/kernel/dma.c
+++ b/arch/hexagon/kernel/dma.c
@@ -207,7 +207,6 @@ const struct dma_map_ops hexagon_dma_ops = {
 	.sync_single_for_cpu = hexagon_sync_single_for_cpu,
 	.sync_single_for_device = hexagon_sync_single_for_device,
 	.mapping_error	= hexagon_mapping_error,
-	.is_phys	= 1,
 };
 
 void __init hexagon_dma_init(void)
diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c
index aec4a3354abe..bc6daf7dace4 100644
--- a/arch/ia64/hp/common/sba_iommu.c
+++ b/arch/ia64/hp/common/sba_iommu.c
@@ -1845,9 +1845,6 @@ static void ioc_init(unsigned long hpa, struct ioc *ioc)
 	ioc_resource_init(ioc);
 	ioc_sac_init(ioc);
 
-	if ((long) ~iovp_mask > (long) ia64_max_iommu_merge_mask)
-		ia64_max_iommu_merge_mask = ~iovp_mask;
-
 	printk(KERN_INFO PFX
 		"%s %d.%d HPA 0x%lx IOVA space %dMb at 0x%lx\n",
 		ioc->name, (ioc->rev >> 4) & 0xF, ioc->rev & 0xF,
@@ -2229,6 +2226,7 @@ const struct dma_map_ops sba_dma_ops = {
 	.sync_sg_for_device	= machvec_dma_sync_sg,
 	.dma_supported		= sba_dma_supported,
 	.mapping_error		= sba_dma_mapping_error,
+	.is_iommu		= true,
 };
 
 void sba_dma_init(void)
diff --git a/arch/ia64/include/asm/pci.h b/arch/ia64/include/asm/pci.h
index b1d04e8bafc8..780e8744ba85 100644
--- a/arch/ia64/include/asm/pci.h
+++ b/arch/ia64/include/asm/pci.h
@@ -30,23 +30,6 @@ struct pci_vector_struct {
 #define PCIBIOS_MIN_IO		0x1000
 #define PCIBIOS_MIN_MEM		0x10000000
 
-/*
- * PCI_DMA_BUS_IS_PHYS should be set to 1 if there is _necessarily_ a direct
- * correspondence between device bus addresses and CPU physical addresses.
- * Platforms with a hardware I/O MMU _must_ turn this off to suppress the
- * bounce buffer handling code in the block and network device layers.
- * Platforms with separate bus address spaces _must_ turn this off and provide
- * a device DMA mapping implementation that takes care of the necessary
- * address translation.
- *
- * For now, the ia64 platforms which may have separate/multiple bus address
- * spaces all have I/O MMUs which support the merging of physically
- * discontiguous buffers, so we can use that as the sole factor to determine
- * the setting of PCI_DMA_BUS_IS_PHYS.
- */
-extern unsigned long ia64_max_iommu_merge_mask;
-#define PCI_DMA_BUS_IS_PHYS	(ia64_max_iommu_merge_mask == ~0UL)
-
 #define HAVE_PCI_MMAP
 #define ARCH_GENERIC_PCI_MMAP_RESOURCE
 #define arch_can_pci_mmap_wc()	1
diff --git a/arch/ia64/kernel/pci-swiotlb.c b/arch/ia64/kernel/pci-swiotlb.c
index 5e50939aa03e..497f7a02d1ae 100644
--- a/arch/ia64/kernel/pci-swiotlb.c
+++ b/arch/ia64/kernel/pci-swiotlb.c
@@ -44,6 +44,7 @@ const struct dma_map_ops swiotlb_dma_ops = {
 	.sync_sg_for_device = swiotlb_sync_sg_for_device,
 	.dma_supported = swiotlb_dma_supported,
 	.mapping_error = swiotlb_dma_mapping_error,
+	.is_iommu = true,
 };
 
 void __init swiotlb_dma_init(void)
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
index dee56bcb993d..ad43cbf70628 100644
--- a/arch/ia64/kernel/setup.c
+++ b/arch/ia64/kernel/setup.c
@@ -123,18 +123,6 @@ unsigned long ia64_i_cache_stride_shift = ~0;
 #define	CACHE_STRIDE_SHIFT	5
 unsigned long ia64_cache_stride_shift = ~0;
 
-/*
- * The merge_mask variable needs to be set to (max(iommu_page_size(iommu)) - 1).  This
- * mask specifies a mask of address bits that must be 0 in order for two buffers to be
- * mergeable by the I/O MMU (i.e., the end address of the first buffer and the start
- * address of the second buffer must be aligned to (merge_mask+1) in order to be
- * mergeable).  By default, we assume there is no I/O MMU which can merge physically
- * discontiguous buffers, so we set the merge_mask to ~0UL, which corresponds to a iommu
- * page-size of 2^64.
- */
-unsigned long ia64_max_iommu_merge_mask = ~0UL;
-EXPORT_SYMBOL(ia64_max_iommu_merge_mask);
-
 /*
  * We use a special marker for the end of memory and it uses the extra (+1) slot
  */
diff --git a/arch/ia64/sn/kernel/io_common.c b/arch/ia64/sn/kernel/io_common.c
index 11f2275570fb..8479e9a7ce16 100644
--- a/arch/ia64/sn/kernel/io_common.c
+++ b/arch/ia64/sn/kernel/io_common.c
@@ -480,11 +480,6 @@ sn_io_early_init(void)
 	tioca_init_provider();
 	tioce_init_provider();
 
-	/*
-	 * This is needed to avoid bounce limit checks in the blk layer
-	 */
-	ia64_max_iommu_merge_mask = ~PAGE_MASK;
-
 	sn_irq_lh_init();
 	INIT_LIST_HEAD(&sn_sysdata_list);
 	sn_init_cpei_timer();
diff --git a/arch/ia64/sn/pci/pci_dma.c b/arch/ia64/sn/pci/pci_dma.c
index 74c934a997bb..350533db030d 100644
--- a/arch/ia64/sn/pci/pci_dma.c
+++ b/arch/ia64/sn/pci/pci_dma.c
@@ -473,6 +473,7 @@ static struct dma_map_ops sn_dma_ops = {
 	.sync_sg_for_device	= sn_dma_sync_sg_for_device,
 	.mapping_error		= sn_dma_mapping_error,
 	.dma_supported		= sn_dma_supported,
+	.is_iommu		= true,
 };
 
 void sn_dma_init(void)
diff --git a/arch/m68k/include/asm/pci.h b/arch/m68k/include/asm/pci.h
index ef26fae8cf0b..5a4bc223743b 100644
--- a/arch/m68k/include/asm/pci.h
+++ b/arch/m68k/include/asm/pci.h
@@ -4,12 +4,6 @@
 
 #include <asm-generic/pci.h>
 
-/* The PCI address space does equal the physical memory
- * address space.  The networking and block device layers use
- * this boolean for bounce buffer decisions.
- */
-#define PCI_DMA_BUS_IS_PHYS	(1)
-
 #define	pcibios_assign_all_busses()	1
 
 #define	PCIBIOS_MIN_IO		0x00000100
diff --git a/arch/microblaze/include/asm/pci.h b/arch/microblaze/include/asm/pci.h
index 114b93488193..00478965f932 100644
--- a/arch/microblaze/include/asm/pci.h
+++ b/arch/microblaze/include/asm/pci.h
@@ -61,12 +61,6 @@ extern int pci_mmap_legacy_page_range(struct pci_bus *bus,
 
 #define HAVE_PCI_LEGACY	1
 
-/* The PCI address space does equal the physical memory
- * address space (no IOMMU).  The IDE and SCSI device layers use
- * this boolean for bounce buffer decisions.
- */
-#define PCI_DMA_BUS_IS_PHYS     (1)
-
 extern void pcibios_claim_one_bus(struct pci_bus *b);
 
 extern void pcibios_finish_adding_to_bus(struct pci_bus *bus);
diff --git a/arch/mips/include/asm/pci.h b/arch/mips/include/asm/pci.h
index 2339f42f047a..436099883022 100644
--- a/arch/mips/include/asm/pci.h
+++ b/arch/mips/include/asm/pci.h
@@ -121,13 +121,6 @@ extern unsigned long PCIBIOS_MIN_MEM;
 #include <linux/string.h>
 #include <asm/io.h>
 
-/*
- * The PCI address space does equal the physical memory address space.
- * The networking and block device layers use this boolean for bounce
- * buffer decisions.
- */
-#define PCI_DMA_BUS_IS_PHYS     (1)
-
 #ifdef CONFIG_PCI_DOMAINS_GENERIC
 static inline int pci_proc_domain(struct pci_bus *bus)
 {
diff --git a/arch/mn10300/include/asm/pci.h b/arch/mn10300/include/asm/pci.h
index 5b75a1b2c4f6..6132966bdf30 100644
--- a/arch/mn10300/include/asm/pci.h
+++ b/arch/mn10300/include/asm/pci.h
@@ -57,12 +57,6 @@ extern void unit_pci_init(void);
 #include <linux/string.h>
 #include <asm/io.h>
 
-/* The PCI address space does equal the physical memory
- * address space.  The networking and block device layers use
- * this boolean for bounce buffer decisions.
- */
-#define PCI_DMA_BUS_IS_PHYS	(1)
-
 /* Return the index of the PCI controller for device. */
 static inline int pci_controller_num(struct pci_dev *dev)
 {
diff --git a/arch/parisc/include/asm/pci.h b/arch/parisc/include/asm/pci.h
index 96b7deec512d..3328fd17c19d 100644
--- a/arch/parisc/include/asm/pci.h
+++ b/arch/parisc/include/asm/pci.h
@@ -87,29 +87,6 @@ struct pci_hba_data {
 #define PCI_F_EXTEND		0UL
 #endif /* !CONFIG_64BIT */
 
-/*
- * If the PCI device's view of memory is the same as the CPU's view of memory,
- * PCI_DMA_BUS_IS_PHYS is true.  The networking and block device layers use
- * this boolean for bounce buffer decisions.
- */
-#ifdef CONFIG_PA20
-/* All PA-2.0 machines have an IOMMU. */
-#define PCI_DMA_BUS_IS_PHYS	0
-#define parisc_has_iommu()	do { } while (0)
-#else
-
-#if defined(CONFIG_IOMMU_CCIO) || defined(CONFIG_IOMMU_SBA)
-extern int parisc_bus_is_phys; 	/* in arch/parisc/kernel/setup.c */
-#define PCI_DMA_BUS_IS_PHYS	parisc_bus_is_phys
-#define parisc_has_iommu()	do { parisc_bus_is_phys = 0; } while (0)
-#else
-#define PCI_DMA_BUS_IS_PHYS	1
-#define parisc_has_iommu()	do { } while (0)
-#endif
-
-#endif	/* !CONFIG_PA20 */
-
-
 /*
 ** Most PCI devices (eg Tulip, NCR720) also export the same registers
 ** to both MMIO and I/O port space.  Due to poor performance of I/O Port
diff --git a/arch/parisc/kernel/setup.c b/arch/parisc/kernel/setup.c
index 0e9675f857a5..8d3a7b80ac42 100644
--- a/arch/parisc/kernel/setup.c
+++ b/arch/parisc/kernel/setup.c
@@ -58,11 +58,6 @@ struct proc_dir_entry * proc_runway_root __read_mostly = NULL;
 struct proc_dir_entry * proc_gsc_root __read_mostly = NULL;
 struct proc_dir_entry * proc_mckinley_root __read_mostly = NULL;
 
-#if !defined(CONFIG_PA20) && (defined(CONFIG_IOMMU_CCIO) || defined(CONFIG_IOMMU_SBA))
-int parisc_bus_is_phys __read_mostly = 1;	/* Assume no IOMMU is present */
-EXPORT_SYMBOL(parisc_bus_is_phys);
-#endif
-
 void __init setup_cmdline(char **cmdline_p)
 {
 	extern unsigned int boot_args[];
diff --git a/arch/powerpc/include/asm/pci.h b/arch/powerpc/include/asm/pci.h
index 8dc32eacc97c..04c1347e2c51 100644
--- a/arch/powerpc/include/asm/pci.h
+++ b/arch/powerpc/include/asm/pci.h
@@ -91,24 +91,6 @@ extern int pci_mmap_legacy_page_range(struct pci_bus *bus,
 
 #define HAVE_PCI_LEGACY	1
 
-#ifdef CONFIG_PPC64
-
-/* The PCI address space does not equal the physical memory address
- * space (we have an IOMMU).  The IDE and SCSI device layers use
- * this boolean for bounce buffer decisions.
- */
-#define PCI_DMA_BUS_IS_PHYS	(0)
-
-#else /* 32-bit */
-
-/* The PCI address space does equal the physical memory
- * address space (no IOMMU).  The IDE and SCSI device layers use
- * this boolean for bounce buffer decisions.
- */
-#define PCI_DMA_BUS_IS_PHYS     (1)
-
-#endif /* CONFIG_PPC64 */
-
 extern void pcibios_claim_one_bus(struct pci_bus *b);
 
 extern void pcibios_finish_adding_to_bus(struct pci_bus *bus);
diff --git a/arch/powerpc/kernel/dma-iommu.c b/arch/powerpc/kernel/dma-iommu.c
index 66f33e7f8d40..77460f543156 100644
--- a/arch/powerpc/kernel/dma-iommu.c
+++ b/arch/powerpc/kernel/dma-iommu.c
@@ -122,5 +122,6 @@ struct dma_map_ops dma_iommu_ops = {
 	.unmap_page		= dma_iommu_unmap_page,
 	.get_required_mask	= dma_iommu_get_required_mask,
 	.mapping_error		= dma_iommu_mapping_error,
+	.is_iommu		= true,
 };
 EXPORT_SYMBOL(dma_iommu_ops);
diff --git a/arch/powerpc/kernel/dma-swiotlb.c b/arch/powerpc/kernel/dma-swiotlb.c
index d0ea7860e02b..1c6388e4c5f3 100644
--- a/arch/powerpc/kernel/dma-swiotlb.c
+++ b/arch/powerpc/kernel/dma-swiotlb.c
@@ -61,6 +61,7 @@ const struct dma_map_ops swiotlb_dma_ops = {
 	.sync_sg_for_device = swiotlb_sync_sg_for_device,
 	.mapping_error = swiotlb_dma_mapping_error,
 	.get_required_mask = swiotlb_powerpc_get_required,
+	.is_iommu = true,
 };
 
 void pci_dma_dev_setup_swiotlb(struct pci_dev *pdev)
diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c
index 4b91ad08eefd..821d302c73eb 100644
--- a/arch/powerpc/platforms/cell/iommu.c
+++ b/arch/powerpc/platforms/cell/iommu.c
@@ -655,6 +655,7 @@ static const struct dma_map_ops dma_iommu_fixed_ops = {
 	.map_page       = dma_fixed_map_page,
 	.unmap_page     = dma_fixed_unmap_page,
 	.mapping_error	= dma_iommu_mapping_error,
+	.is_iommu	= true,
 };
 
 static void cell_dma_dev_setup(struct device *dev)
diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c
index 5cc35d6b94b6..1e5348ad50e4 100644
--- a/arch/powerpc/platforms/ps3/system-bus.c
+++ b/arch/powerpc/platforms/ps3/system-bus.c
@@ -712,6 +712,7 @@ static const struct dma_map_ops ps3_sb_dma_ops = {
 	.get_required_mask = ps3_dma_get_required_mask,
 	.map_page = ps3_sb_map_page,
 	.unmap_page = ps3_unmap_page,
+	.is_iommu = true,
 };
 
 static const struct dma_map_ops ps3_ioc0_dma_ops = {
@@ -723,6 +724,7 @@ static const struct dma_map_ops ps3_ioc0_dma_ops = {
 	.get_required_mask = ps3_dma_get_required_mask,
 	.map_page = ps3_ioc0_map_page,
 	.unmap_page = ps3_unmap_page,
+	.is_iommu = true,
 };
 
 /**
diff --git a/arch/powerpc/platforms/pseries/ibmebus.c b/arch/powerpc/platforms/pseries/ibmebus.c
index 408a86044133..d99b25f05220 100644
--- a/arch/powerpc/platforms/pseries/ibmebus.c
+++ b/arch/powerpc/platforms/pseries/ibmebus.c
@@ -145,6 +145,7 @@ static const struct dma_map_ops ibmebus_dma_ops = {
 	.get_required_mask  = ibmebus_dma_get_required_mask,
 	.map_page           = ibmebus_map_page,
 	.unmap_page         = ibmebus_unmap_page,
+	.is_iommu           = true,
 };
 
 static int ibmebus_match_path(struct device *dev, void *data)
diff --git a/arch/powerpc/platforms/pseries/vio.c b/arch/powerpc/platforms/pseries/vio.c
index d86938260a86..9d65105c5d1a 100644
--- a/arch/powerpc/platforms/pseries/vio.c
+++ b/arch/powerpc/platforms/pseries/vio.c
@@ -626,6 +626,7 @@ static const struct dma_map_ops vio_dma_mapping_ops = {
 	.dma_supported     = vio_dma_iommu_dma_supported,
 	.get_required_mask = vio_dma_get_required_mask,
 	.mapping_error	   = dma_iommu_mapping_error,
+	.is_iommu          = true,
 };
 
 /**
diff --git a/arch/riscv/include/asm/pci.h b/arch/riscv/include/asm/pci.h
index 0f2fc9ef20fc..b3638c505728 100644
--- a/arch/riscv/include/asm/pci.h
+++ b/arch/riscv/include/asm/pci.h
@@ -26,9 +26,6 @@
 /* RISC-V shim does not initialize PCI bus */
 #define pcibios_assign_all_busses() 1
 
-/* We do not have an IOMMU */
-#define PCI_DMA_BUS_IS_PHYS 1
-
 extern int isa_dma_bridge_buggy;
 
 #ifdef CONFIG_PCI
diff --git a/arch/s390/include/asm/pci.h b/arch/s390/include/asm/pci.h
index 12fe3591034f..94f8db468c9b 100644
--- a/arch/s390/include/asm/pci.h
+++ b/arch/s390/include/asm/pci.h
@@ -2,8 +2,6 @@
 #ifndef __ASM_S390_PCI_H
 #define __ASM_S390_PCI_H
 
-/* must be set before including asm-generic/pci.h */
-#define PCI_DMA_BUS_IS_PHYS (0)
 /* must be set before including pci_clp.h */
 #define PCI_BAR_COUNT	6
 
diff --git a/arch/s390/pci/pci_dma.c b/arch/s390/pci/pci_dma.c
index f7aa5a77827e..76ae7020ff21 100644
--- a/arch/s390/pci/pci_dma.c
+++ b/arch/s390/pci/pci_dma.c
@@ -668,8 +668,7 @@ const struct dma_map_ops s390_pci_dma_ops = {
 	.map_page	= s390_dma_map_pages,
 	.unmap_page	= s390_dma_unmap_pages,
 	.mapping_error	= s390_mapping_error,
-	/* if we support direct DMA this must be conditional */
-	.is_phys	= 0,
+	.is_iommu	= true,
 	/* dma_supported is unconditionally true without a callback */
 };
 EXPORT_SYMBOL_GPL(s390_pci_dma_ops);
diff --git a/arch/sh/include/asm/pci.h b/arch/sh/include/asm/pci.h
index 0033f0df2b3b..10a36b1cf2ea 100644
--- a/arch/sh/include/asm/pci.h
+++ b/arch/sh/include/asm/pci.h
@@ -71,12 +71,6 @@ extern unsigned long PCIBIOS_MIN_IO, PCIBIOS_MIN_MEM;
  * SuperH has everything mapped statically like x86.
  */
 
-/* The PCI address space does equal the physical memory
- * address space.  The networking and block device layers use
- * this boolean for bounce buffer decisions.
- */
-#define PCI_DMA_BUS_IS_PHYS	(dma_ops->is_phys)
-
 #ifdef CONFIG_PCI
 /*
  * None of the SH PCI controllers support MWI, it is always treated as a
diff --git a/arch/sh/kernel/dma-nommu.c b/arch/sh/kernel/dma-nommu.c
index 62b485107eae..2077cfe73cc6 100644
--- a/arch/sh/kernel/dma-nommu.c
+++ b/arch/sh/kernel/dma-nommu.c
@@ -75,7 +75,6 @@ const struct dma_map_ops nommu_dma_ops = {
 	.sync_single_for_device	= nommu_sync_single_for_device,
 	.sync_sg_for_device	= nommu_sync_sg_for_device,
 #endif
-	.is_phys		= 1,
 };
 
 void __init no_iommu_init(void)
diff --git a/arch/sparc/include/asm/pci_32.h b/arch/sparc/include/asm/pci_32.h
index 98917e48727d..cfc0ee9476c6 100644
--- a/arch/sparc/include/asm/pci_32.h
+++ b/arch/sparc/include/asm/pci_32.h
@@ -17,10 +17,6 @@
 
 #define PCI_IRQ_NONE		0xffffffff
 
-/* Dynamic DMA mapping stuff.
- */
-#define PCI_DMA_BUS_IS_PHYS	(0)
-
 #endif /* __KERNEL__ */
 
 #ifndef CONFIG_LEON_PCI
diff --git a/arch/sparc/include/asm/pci_64.h b/arch/sparc/include/asm/pci_64.h
index 671274e36cfa..fac77813402c 100644
--- a/arch/sparc/include/asm/pci_64.h
+++ b/arch/sparc/include/asm/pci_64.h
@@ -17,12 +17,6 @@
 
 #define PCI_IRQ_NONE		0xffffffff
 
-/* The PCI address space does not equal the physical memory
- * address space.  The networking and block device layers use
- * this boolean for bounce buffer decisions.
- */
-#define PCI_DMA_BUS_IS_PHYS	(0)
-
 /* PCI IOMMU mapping bypass support. */
 
 /* PCI 64-bit addressing works for all slots on all controller
diff --git a/arch/sparc/kernel/iommu.c b/arch/sparc/kernel/iommu.c
index b08dc3416f06..a5115dc7545a 100644
--- a/arch/sparc/kernel/iommu.c
+++ b/arch/sparc/kernel/iommu.c
@@ -773,6 +773,7 @@ static const struct dma_map_ops sun4u_dma_ops = {
 	.sync_sg_for_cpu	= dma_4u_sync_sg_for_cpu,
 	.dma_supported		= dma_4u_supported,
 	.mapping_error		= dma_4u_mapping_error,
+	.is_iommu		= true,
 };
 
 const struct dma_map_ops *dma_ops = &sun4u_dma_ops;
diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c
index 7eeef80c02f7..7d81281d3b5a 100644
--- a/arch/sparc/kernel/ioport.c
+++ b/arch/sparc/kernel/ioport.c
@@ -417,6 +417,7 @@ static const struct dma_map_ops sbus_dma_ops = {
 	.sync_sg_for_cpu	= sbus_sync_sg_for_cpu,
 	.sync_sg_for_device	= sbus_sync_sg_for_device,
 	.dma_supported		= sbus_dma_supported,
+	.is_iommu		= true,
 };
 
 static int __init sparc_register_ioport(void)
diff --git a/arch/sparc/kernel/pci_sun4v.c b/arch/sparc/kernel/pci_sun4v.c
index 249367228c33..77b920580a9a 100644
--- a/arch/sparc/kernel/pci_sun4v.c
+++ b/arch/sparc/kernel/pci_sun4v.c
@@ -702,6 +702,7 @@ static const struct dma_map_ops sun4v_dma_ops = {
 	.unmap_sg			= dma_4v_unmap_sg,
 	.dma_supported			= dma_4v_supported,
 	.mapping_error			= dma_4v_mapping_error,
+	.is_iommu			= true,
 };
 
 static void pci_sun4v_scan_bus(struct pci_pbm_info *pbm, struct device *parent)
diff --git a/arch/tile/include/asm/pci.h b/arch/tile/include/asm/pci.h
index fe3de505b024..8b910e3f0620 100644
--- a/arch/tile/include/asm/pci.h
+++ b/arch/tile/include/asm/pci.h
@@ -52,13 +52,6 @@ static inline void pci_iounmap(struct pci_dev *dev, void __iomem *addr) {}
 
 #define	TILE_NUM_PCIE	2
 
-/*
- * The hypervisor maps the entirety of CPA-space as bus addresses, so
- * bus addresses are physical addresses.  The networking and block
- * device layers use this boolean for bounce buffer decisions.
- */
-#define PCI_DMA_BUS_IS_PHYS     1
-
 /* generic pci stuff */
 #include <asm-generic/pci.h>
 
@@ -185,13 +178,6 @@ extern int num_trio_shims;
 
 extern void pci_iounmap(struct pci_dev *dev, void __iomem *);
 
-/*
- * The PCI address space does not equal the physical memory address
- * space (we have an IOMMU). The IDE and SCSI device layers use this
- * boolean for bounce buffer decisions.
- */
-#define PCI_DMA_BUS_IS_PHYS     0
-
 #endif /* __tilegx__ */
 
 int __init tile_pci_init(void);
diff --git a/arch/tile/kernel/pci-dma.c b/arch/tile/kernel/pci-dma.c
index f2abedc8a080..81d0c2079fc8 100644
--- a/arch/tile/kernel/pci-dma.c
+++ b/arch/tile/kernel/pci-dma.c
@@ -537,6 +537,7 @@ static const struct dma_map_ops pci_swiotlb_dma_ops = {
 	.sync_sg_for_device = swiotlb_sync_sg_for_device,
 	.dma_supported = swiotlb_dma_supported,
 	.mapping_error = swiotlb_dma_mapping_error,
+	.is_iommu = true,
 };
 
 static const struct dma_map_ops pci_hybrid_dma_ops = {
@@ -550,6 +551,7 @@ static const struct dma_map_ops pci_hybrid_dma_ops = {
 	.sync_single_for_device = tile_pci_dma_sync_single_for_device,
 	.sync_sg_for_cpu = tile_pci_dma_sync_sg_for_cpu,
 	.sync_sg_for_device = tile_pci_dma_sync_sg_for_device,
+	.is_iommu = true,
 };
 
 const struct dma_map_ops *gx_legacy_pci_dma_map_ops = &pci_swiotlb_dma_ops;
diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h
index d32175e30259..fecde74ff549 100644
--- a/arch/x86/include/asm/pci.h
+++ b/arch/x86/include/asm/pci.h
@@ -118,8 +118,6 @@ void native_restore_msi_irqs(struct pci_dev *dev);
 #define native_teardown_msi_irq		NULL
 #endif
 
-#define PCI_DMA_BUS_IS_PHYS (dma_ops->is_phys)
-
 #endif  /* __KERNEL__ */
 
 #ifdef CONFIG_X86_64
diff --git a/arch/x86/kernel/amd_gart_64.c b/arch/x86/kernel/amd_gart_64.c
index cc0e8bc0ea3f..a837d24cbca3 100644
--- a/arch/x86/kernel/amd_gart_64.c
+++ b/arch/x86/kernel/amd_gart_64.c
@@ -705,6 +705,7 @@ static const struct dma_map_ops gart_dma_ops = {
 	.free				= gart_free_coherent,
 	.mapping_error			= gart_mapping_error,
 	.dma_supported			= x86_dma_supported,
+	.is_iommu			= true,
 };
 
 static void gart_iommu_shutdown(void)
diff --git a/arch/x86/kernel/pci-calgary_64.c b/arch/x86/kernel/pci-calgary_64.c
index 35c461f21815..83f1e4feeede 100644
--- a/arch/x86/kernel/pci-calgary_64.c
+++ b/arch/x86/kernel/pci-calgary_64.c
@@ -494,6 +494,7 @@ static const struct dma_map_ops calgary_dma_ops = {
 	.unmap_page = calgary_unmap_page,
 	.mapping_error = calgary_mapping_error,
 	.dma_supported = x86_dma_supported,
+	.is_iommu = true,
 };
 
 static inline void __iomem * busno_to_bbar(unsigned char num)
diff --git a/arch/x86/kernel/pci-nommu.c b/arch/x86/kernel/pci-nommu.c
index b0caae27e1b7..0a2a8e629381 100644
--- a/arch/x86/kernel/pci-nommu.c
+++ b/arch/x86/kernel/pci-nommu.c
@@ -103,7 +103,6 @@ const struct dma_map_ops nommu_dma_ops = {
 	.map_page		= nommu_map_page,
 	.sync_single_for_device = nommu_sync_single_for_device,
 	.sync_sg_for_device	= nommu_sync_sg_for_device,
-	.is_phys		= 1,
 	.mapping_error		= nommu_mapping_error,
 	.dma_supported		= x86_dma_supported,
 };
diff --git a/arch/x86/kernel/pci-swiotlb.c b/arch/x86/kernel/pci-swiotlb.c
index 53bd05ea90d8..f08953617841 100644
--- a/arch/x86/kernel/pci-swiotlb.c
+++ b/arch/x86/kernel/pci-swiotlb.c
@@ -61,6 +61,7 @@ static const struct dma_map_ops swiotlb_dma_ops = {
 	.map_page = swiotlb_map_page,
 	.unmap_page = swiotlb_unmap_page,
 	.dma_supported = NULL,
+	.is_iommu = true,
 };
 
 /*
diff --git a/arch/x86/mm/mem_encrypt.c b/arch/x86/mm/mem_encrypt.c
index d9a9e9fc75dd..cccbd7bff0d6 100644
--- a/arch/x86/mm/mem_encrypt.c
+++ b/arch/x86/mm/mem_encrypt.c
@@ -425,6 +425,7 @@ static const struct dma_map_ops sev_dma_ops = {
 	.sync_sg_for_cpu        = swiotlb_sync_sg_for_cpu,
 	.sync_sg_for_device     = swiotlb_sync_sg_for_device,
 	.mapping_error          = swiotlb_dma_mapping_error,
+	.is_iommu		= true,
 };
 
 /* Architecture __weak replacement functions */
diff --git a/arch/x86/pci/sta2x11-fixup.c b/arch/x86/pci/sta2x11-fixup.c
index 53d600217973..a03e1c6a1aea 100644
--- a/arch/x86/pci/sta2x11-fixup.c
+++ b/arch/x86/pci/sta2x11-fixup.c
@@ -193,6 +193,7 @@ static const struct dma_map_ops sta2x11_dma_ops = {
 	.sync_sg_for_device = swiotlb_sync_sg_for_device,
 	.mapping_error = swiotlb_dma_mapping_error,
 	.dma_supported = x86_dma_supported,
+	.is_iommu = true,
 };
 
 /* At setup time, we use our own ops if the device is a ConneXt one */
diff --git a/arch/xtensa/include/asm/pci.h b/arch/xtensa/include/asm/pci.h
index 5c83798e3b2e..7949349294c7 100644
--- a/arch/xtensa/include/asm/pci.h
+++ b/arch/xtensa/include/asm/pci.h
@@ -37,13 +37,6 @@ extern struct pci_controller* pcibios_alloc_controller(void);
 #include <linux/string.h>
 #include <asm/io.h>
 
-/* The PCI address space does equal the physical memory address space.
- * The networking and block device layers use this boolean for bounce buffer
- * decisions.
- */
-
-#define PCI_DMA_BUS_IS_PHYS	(1)
-
 /* Tell drivers/pci/proc.c that we have pci_mmap_page_range() */
 #define HAVE_PCI_MMAP		1
 #define arch_can_pci_mmap_io()	1
diff --git a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c
index e1180fa46196..dca9ac4a9376 100644
--- a/drivers/ide/ide-lib.c
+++ b/drivers/ide/ide-lib.c
@@ -17,13 +17,12 @@
 
 void ide_toggle_bounce(ide_drive_t *drive, int on)
 {
+	struct device *dev = drive->hwif ? drive->hwif->dev : NULL;
 	u64 addr = BLK_BOUNCE_HIGH;	/* dma64_addr_t */
 
-	if (!PCI_DMA_BUS_IS_PHYS) {
+	if (dev && dma_is_iommu(dev)) {
 		addr = BLK_BOUNCE_ANY;
 	} else if (on && drive->media == ide_disk) {
-		struct device *dev = drive->hwif->dev;
-
 		if (dev && dev->dma_mask)
 			addr = *dev->dma_mask;
 	}
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index 17fd55af4d92..33f5c8ec59b1 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -796,7 +796,7 @@ static int ide_init_queue(ide_drive_t *drive)
 	 * This will be fixed once we teach pci_map_sg() about our boundary
 	 * requirements, hopefully soon. *FIXME*
 	 */
-	if (!PCI_DMA_BUS_IS_PHYS)
+	if (hwif->dev && dma_is_iommu(hwif->dev))
 		max_sg_entries >>= 1;
 #endif /* CONFIG_PCI */
 
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index 7d5eb004091d..84ec2ccfd6f7 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -2686,6 +2686,7 @@ static const struct dma_map_ops amd_iommu_dma_ops = {
 	.unmap_sg	= unmap_sg,
 	.dma_supported	= amd_iommu_dma_supported,
 	.mapping_error	= amd_iommu_mapping_error,
+	.is_iommu	= true,
 };
 
 static int init_reserved_iova_ranges(void)
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index a0babdbf7146..568eb86c5bf4 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -3872,6 +3872,7 @@ const struct dma_map_ops intel_dma_ops = {
 #ifdef CONFIG_X86
 	.dma_supported = x86_dma_supported,
 #endif
+	.is_iommu = true,
 };
 
 static inline int iommu_domain_cache_init(void)
diff --git a/drivers/parisc/ccio-dma.c b/drivers/parisc/ccio-dma.c
index acba1f56af3e..3e7f3a14a1a2 100644
--- a/drivers/parisc/ccio-dma.c
+++ b/drivers/parisc/ccio-dma.c
@@ -1039,6 +1039,7 @@ static const struct dma_map_ops ccio_ops = {
 	.map_sg = 		ccio_map_sg,
 	.unmap_sg = 		ccio_unmap_sg,
 	.mapping_error =	ccio_mapping_error,
+	.is_iommu =		true,
 };
 
 #ifdef CONFIG_PROC_FS
@@ -1596,8 +1597,6 @@ static int __init ccio_probe(struct parisc_device *dev)
 	}
 #endif
 	ioc_count++;
-
-	parisc_has_iommu();
 	return 0;
 }
 
diff --git a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c
index 0a9c762a70fa..f6e92a7a3607 100644
--- a/drivers/parisc/sba_iommu.c
+++ b/drivers/parisc/sba_iommu.c
@@ -1099,6 +1099,7 @@ static const struct dma_map_ops sba_ops = {
 	.map_sg =		sba_map_sg,
 	.unmap_sg =		sba_unmap_sg,
 	.mapping_error =	sba_mapping_error,
+	.is_iommu =		true,
 };
 
 
@@ -2017,8 +2018,6 @@ static int __init sba_driver_callback(struct parisc_device *dev)
 	proc_create("sba_iommu", 0, root, &sba_proc_fops);
 	proc_create("sba_iommu-bitmap", 0, root, &sba_proc_bitmap_fops);
 #endif
-
-	parisc_has_iommu();
 	return 0;
 }
 
diff --git a/drivers/pci/host/vmd.c b/drivers/pci/host/vmd.c
index 509893bc3e63..b9a750721211 100644
--- a/drivers/pci/host/vmd.c
+++ b/drivers/pci/host/vmd.c
@@ -428,6 +428,7 @@ static void vmd_setup_dma_ops(struct vmd_dev *vmd)
 #ifdef ARCH_HAS_DMA_GET_REQUIRED_MASK
 	ASSIGN_VMD_DMA_OPS(source, dest, get_required_mask);
 #endif
+	ASSIGN_VMD_DMA_OPS(source, dest, is_iommu);
 	add_dma_domain(domain);
 }
 #undef ASSIGN_VMD_DMA_OPS
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 1cbc497e00bd..7d78f7bc1126 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -2103,16 +2103,14 @@ static u64 scsi_calculate_bounce_limit(struct Scsi_Host *shost)
 
 	if (shost->unchecked_isa_dma)
 		return BLK_BOUNCE_ISA;
-	/*
-	 * Platforms with virtual-DMA translation
-	 * hardware have no practical limit.
-	 */
-	if (!PCI_DMA_BUS_IS_PHYS)
-		return BLK_BOUNCE_ANY;
 
 	host_dev = scsi_get_device(shost);
-	if (host_dev && host_dev->dma_mask)
-		bounce_limit = (u64)dma_max_pfn(host_dev) << PAGE_SHIFT;
+	if (host_dev) {
+		if (dma_is_iommu(host_dev))
+			return BLK_BOUNCE_ANY;
+		if (host_dev->dma_mask)
+			bounce_limit = (u64)dma_max_pfn(host_dev) << PAGE_SHIFT;
+	}
 
 	return bounce_limit;
 }
diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c
index 82fc54f8eb77..ced9ac999d5a 100644
--- a/drivers/xen/swiotlb-xen.c
+++ b/drivers/xen/swiotlb-xen.c
@@ -726,4 +726,5 @@ const struct dma_map_ops xen_swiotlb_dma_ops = {
 	.mmap = xen_swiotlb_dma_mmap,
 	.get_sgtable = xen_swiotlb_get_sgtable,
 	.mapping_error	= xen_swiotlb_mapping_error,
+	.is_iommu = true,
 };
diff --git a/include/asm-generic/pci.h b/include/asm-generic/pci.h
index 830d7659289b..6bb3cd3d695a 100644
--- a/include/asm-generic/pci.h
+++ b/include/asm-generic/pci.h
@@ -14,12 +14,4 @@ static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
 }
 #endif /* HAVE_ARCH_PCI_GET_LEGACY_IDE_IRQ */
 
-/*
- * By default, assume that no iommu is in use and that the PCI
- * space is mapped to address physical 0.
- */
-#ifndef PCI_DMA_BUS_IS_PHYS
-#define PCI_DMA_BUS_IS_PHYS	(1)
-#endif
-
 #endif /* _ASM_GENERIC_PCI_H */
diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
index 86beb9861618..7201849703cc 100644
--- a/include/linux/dma-mapping.h
+++ b/include/linux/dma-mapping.h
@@ -133,7 +133,7 @@ struct dma_map_ops {
 #ifdef ARCH_HAS_DMA_GET_REQUIRED_MASK
 	u64 (*get_required_mask)(struct device *dev);
 #endif
-	int is_phys;
+	bool is_iommu;	/* if true can map any physical address */
 };
 
 extern const struct dma_map_ops dma_noop_ops;
@@ -689,6 +689,20 @@ static inline int dma_set_seg_boundary(struct device *dev, unsigned long mask)
 	return -EIO;
 }
 
+#ifdef CONFIG_HAS_DMA
+static inline bool dma_is_iommu(struct device *dev)
+{
+	const struct dma_map_ops *ops = get_dma_ops(dev);
+
+	return ops && ops->is_iommu;
+}
+#else
+static inline bool dma_is_iommu(struct device *dev)
+{
+	return false;
+}
+#endif
+
 #ifndef dma_max_pfn
 static inline unsigned long dma_max_pfn(struct device *dev)
 {
diff --git a/lib/dma-virt.c b/lib/dma-virt.c
index 8e61a02ef9ca..b652ecb853fa 100644
--- a/lib/dma-virt.c
+++ b/lib/dma-virt.c
@@ -57,5 +57,6 @@ const struct dma_map_ops dma_virt_ops = {
 	.free			= dma_virt_free,
 	.map_page		= dma_virt_map_page,
 	.map_sg			= dma_virt_map_sg,
+	.is_iommu		= true,
 };
 EXPORT_SYMBOL(dma_virt_ops);
diff --git a/net/core/dev.c b/net/core/dev.c
index 07ed21d64f92..5ccd7ba3fd55 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2830,6 +2830,7 @@ EXPORT_SYMBOL(netdev_rx_csum_fault);
 static int illegal_highdma(struct net_device *dev, struct sk_buff *skb)
 {
 #ifdef CONFIG_HIGHMEM
+	struct device *pdev = dev->dev.parent;
 	int i;
 
 	if (!(dev->features & NETIF_F_HIGHDMA)) {
@@ -2841,18 +2842,15 @@ static int illegal_highdma(struct net_device *dev, struct sk_buff *skb)
 		}
 	}
 
-	if (PCI_DMA_BUS_IS_PHYS) {
-		struct device *pdev = dev->dev.parent;
+	if (!pdev || dma_is_iommu(pdev))
+		return 0;
 
-		if (!pdev)
-			return 0;
-		for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
-			skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
-			dma_addr_t addr = page_to_phys(skb_frag_page(frag));
+	for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+		skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+		dma_addr_t addr = page_to_phys(skb_frag_page(frag));
 
-			if (!pdev->dma_mask || addr + PAGE_SIZE - 1 > *pdev->dma_mask)
-				return 1;
-		}
+		if (!pdev->dma_mask || addr + PAGE_SIZE - 1 > *pdev->dma_mask)
+			return 1;
 	}
 #endif
 	return 0;
diff --git a/tools/virtio/linux/dma-mapping.h b/tools/virtio/linux/dma-mapping.h
index 1571e24e9494..f91aeb5fe571 100644
--- a/tools/virtio/linux/dma-mapping.h
+++ b/tools/virtio/linux/dma-mapping.h
@@ -6,8 +6,6 @@
 # error Virtio userspace code does not support CONFIG_HAS_DMA
 #endif
 
-#define PCI_DMA_BUS_IS_PHYS 1
-
 enum dma_data_direction {
 	DMA_BIDIRECTIONAL = 0,
 	DMA_TO_DEVICE = 1,
-- 
2.14.2

^ permalink raw reply related

* [PATCH 2/3] arm64: don't override dma_max_pfn
From: Christoph Hellwig @ 2017-12-04 16:36 UTC (permalink / raw)
  To: iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	linux-arch-u79uwXL29TY76Z2rM5mHXA,
	linux-block-u79uwXL29TY76Z2rM5mHXA, netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
  Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20171204163601.3055-1-hch-jcswGhMUV9g@public.gmane.org>

The generic version now takes dma_pfn_offset into account, so there is no
more need for an architecture override.

Signed-off-by: Christoph Hellwig <hch-jcswGhMUV9g@public.gmane.org>
---
 arch/arm64/include/asm/dma-mapping.h | 9 ---------
 1 file changed, 9 deletions(-)

diff --git a/arch/arm64/include/asm/dma-mapping.h b/arch/arm64/include/asm/dma-mapping.h
index 0df756b24863..eada887a93bf 100644
--- a/arch/arm64/include/asm/dma-mapping.h
+++ b/arch/arm64/include/asm/dma-mapping.h
@@ -76,14 +76,5 @@ static inline void dma_mark_clean(void *addr, size_t size)
 {
 }
 
-/* Override for dma_max_pfn() */
-static inline unsigned long dma_max_pfn(struct device *dev)
-{
-	dma_addr_t dma_max = (dma_addr_t)*dev->dma_mask;
-
-	return (ulong)dma_to_phys(dev, dma_max) >> PAGE_SHIFT;
-}
-#define dma_max_pfn(dev) dma_max_pfn(dev)
-
 #endif	/* __KERNEL__ */
 #endif	/* __ASM_DMA_MAPPING_H */
-- 
2.14.2

^ permalink raw reply related

* [PATCH 1/3] dma-mapping: take dma_pfn_offset into account in dma_max_pfn
From: Christoph Hellwig @ 2017-12-04 16:35 UTC (permalink / raw)
  To: iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	linux-arch-u79uwXL29TY76Z2rM5mHXA,
	linux-block-u79uwXL29TY76Z2rM5mHXA, netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
  Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20171204163601.3055-1-hch-jcswGhMUV9g@public.gmane.org>

This makes sure the generic version can be used with architectures /
devices that have a DMA offset in the direct mapping.

Signed-off-by: Christoph Hellwig <hch-jcswGhMUV9g@public.gmane.org>
---
 include/linux/dma-mapping.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
index e8f8e8fb244d..86beb9861618 100644
--- a/include/linux/dma-mapping.h
+++ b/include/linux/dma-mapping.h
@@ -692,7 +692,7 @@ static inline int dma_set_seg_boundary(struct device *dev, unsigned long mask)
 #ifndef dma_max_pfn
 static inline unsigned long dma_max_pfn(struct device *dev)
 {
-	return *dev->dma_mask >> PAGE_SHIFT;
+	return (*dev->dma_mask >> PAGE_SHIFT) + dev->dma_pfn_offset;
 }
 #endif
 
-- 
2.14.2

^ permalink raw reply related

* replace PCI_DMA_BUS_IS_PHYS with a per-instance flag
From: Christoph Hellwig @ 2017-12-04 16:35 UTC (permalink / raw)
  To: iommu, linux-arch, linux-block, netdev, linux-arm-kernel; +Cc: linux-kernel

Hi all,

this small series tries to get rid of the global and misnamed
PCI_DMA_BUS_IS_PHYS flag, and replace it with a setting in each
struct dma_map_ops instance.

^ permalink raw reply

* Re: [PATCH net-next 2/4] bnxt_en: Use NETIF_F_GRO_HW.
From: Or Gerlitz @ 2017-12-04 16:35 UTC (permalink / raw)
  To: Michael Chan; +Cc: David Miller, Linux Netdev List
In-Reply-To: <1512385967-32339-3-git-send-email-michael.chan@broadcom.com>

On Mon, Dec 4, 2017 at 1:12 PM, Michael Chan <michael.chan@broadcom.com> wrote:
> Advertise NETIF_F_GRO_HW if hardware GRO is supported.  Turn on or off
> hardware GRO based on NETIF_F_GRO_HW.

So the patch only deals with advertisement biz.. and I even failed to
find a place where you arm
something in the FW... so this just works OOB, all your buffers && skb
logic && FW setup are fully
ready for that? also, nothing you need to put differently on the SKB
for HW GRO completions?
can you explain this little further or it's all in your netdev slides...

Or.

^ permalink raw reply

* Re: [PATCH 03/10] net: ezchip: nps_enet: Fix platform_get_irq's error checking
From: David Miller @ 2017-12-04 16:34 UTC (permalink / raw)
  To: linux
  Cc: arvind.yadav.cs, f.fainelli, netdev, michal.simek, linux-kernel,
	opendmb, mkl, linux-arm-kernel, Vladislav.Zakharov, wg
In-Reply-To: <20171204162447.GT10595@n2100.armlinux.org.uk>

From: Russell King - ARM Linux <linux@armlinux.org.uk>
Date: Mon, 4 Dec 2017 16:24:47 +0000

> On Mon, Dec 04, 2017 at 11:20:49AM -0500, David Miller wrote:
>> From: Arvind Yadav <arvind.yadav.cs@gmail.com>
>> Date: Sun,  3 Dec 2017 00:56:15 +0530
>> 
>> > The platform_get_irq() function returns negative if an error occurs.
>> > zero or positive number on success. platform_get_irq() error checking
>> > for zero is not correct. And remove unnecessary check for free_netdev().
>> > 
>> > Signed-off-by: Arvind Yadav <arvind.yadav.cs@gmail.com>
>> > ---
>> >  drivers/net/ethernet/ezchip/nps_enet.c | 7 +++----
>> >  1 file changed, 3 insertions(+), 4 deletions(-)
>> > 
>> > diff --git a/drivers/net/ethernet/ezchip/nps_enet.c b/drivers/net/ethernet/ezchip/nps_enet.c
>> > index 659f1ad..82dc6d0 100644
>> > --- a/drivers/net/ethernet/ezchip/nps_enet.c
>> > +++ b/drivers/net/ethernet/ezchip/nps_enet.c
>> > @@ -623,9 +623,9 @@ static s32 nps_enet_probe(struct platform_device *pdev)
>> >  
>> >  	/* Get IRQ number */
>> >  	priv->irq = platform_get_irq(pdev, 0);
>> > -	if (!priv->irq) {
>> > +	if (priv->irq <= 0) {
>> >  		dev_err(dev, "failed to retrieve <irq Rx-Tx> value from device tree\n");
>> > -		err = -ENODEV;
>> > +		err = priv->irq ? priv->irq : -ENODEV;
>> 
>> If platform_get_irq() returns "zero or positive number on success" then this
>> test is wrong and should be "if (priv->irq < 0)"
>> 
>> Also, this series is a mix of different kinds of changes.
>> 
>> Please separate out the platform IRQ error checking and just submit exactly
>> those changes as a patch series.
>> 
>> The other bug fixes should be submitted outside of those changes since they
>> are unrelated.
> 
> The issue of whether IRQ 0 is valid or not has been covered several times
> by Linus, and the result is that it is deemed by Linus that IRQ 0 is not
> a valid interrupt.

Then either platform_get_irq() as defined or this commit message (or both)
are wrong.

^ permalink raw reply

* Re: [PATCH next-next 0/4] rtnetlink: rework handler (un)registering
From: David Miller @ 2017-12-04 16:34 UTC (permalink / raw)
  To: fw; +Cc: netdev
In-Reply-To: <20171202204408.4166-1-fw@strlen.de>

From: Florian Westphal <fw@strlen.de>
Date: Sat,  2 Dec 2017 21:44:04 +0100

> Peter Zijlstra reported (referring to commit 019a316992ee0d983,
> "rtnetlink: add reference counting to prevent module unload while dump is in progress"):
> 
>  1) it not in fact a refcount, so using refcount_t is silly
>  2) there is a distinct lack of memory barriers, so we can easily
>     observe the decrement while the msg_handler is still in progress.
>  3) waiting with a schedule()/yield() loop is complete crap and subject
>     life-locks, imagine doing that rtnl_unregister_all() from a RT task.
> 
> In ancient times rtnetlink exposed a statically-sized table with
> preset doit/dumpit handlers to be called for a protocol/type pair.
> 
> Later the rtnl_register interface was added and the table was allocated
> on demand.  Eventually these were also used by modules.
> 
> Problem is that nothing prevents module unload while a netlink dump
> is in progress.  netlink dumps can be span multiple recv calls and
> netlink core saves the to-be-repeated dumper address for later invocation.
> 
> To prevent rmmod the netlink core expects callers to pass in the owning
> module so a reference can be taken.
> 
> So far rtnetlink wasn't doing this, add new interface to pass THIS_MODULE.
> Moreover, when converting parts of the rtnetlink handling to rcu this code
> gained way too many READ_ONCE spots, remove them and the extra refcounting.
> 
> Take a module reference when running dumpit and doit callbacks
> and never alter content of rtnl_link structures after they have been
> published via rcu_assign_pointer.
> 
> Based partially on earlier patch from Peter.

Series applied, thanks Florian.

BTW, why did you use rtnl_register_module() for most of ipv6 but
specifically not for the net/ipv6/addrconf.c stuff?

Just curious.

^ permalink raw reply

* Re: [RFC] virtio-net: help live migrate SR-IOV devices
From: Alexander Duyck @ 2017-12-04 16:30 UTC (permalink / raw)
  To: achiad shochat
  Cc: Stephen Hemminger, Michael S. Tsirkin, Jakub Kicinski,
	Hannes Frederic Sowa, Sridhar Samudrala, netdev, virtualization,
	Achiad, Peter Waskiewicz Jr, Singhai, Anjali, Shannon Nelson,
	Andy Gospodarek, Or Gerlitz
In-Reply-To: <CAEHy93LEr5h81KGfJBr5Z4ZKaeWEWwQL1LYfZNXoVF_HB6TQGw@mail.gmail.com>

On Mon, Dec 4, 2017 at 1:51 AM, achiad shochat
<achiad.mellanox@gmail.com> wrote:
> On 3 December 2017 at 19:35, Stephen Hemminger
> <stephen@networkplumber.org> wrote:
>> On Sun, 3 Dec 2017 11:14:37 +0200
>> achiad shochat <achiad.mellanox@gmail.com> wrote:
>>
>>> On 3 December 2017 at 07:05, Michael S. Tsirkin <mst@redhat.com> wrote:
>>> > On Fri, Dec 01, 2017 at 12:08:59PM -0800, Shannon Nelson wrote:
>>> >> On 11/30/2017 6:11 AM, Michael S. Tsirkin wrote:
>>> >> > On Thu, Nov 30, 2017 at 10:08:45AM +0200, achiad shochat wrote:
>>> >> > > Re. problem #2:
>>> >> > > Indeed the best way to address it seems to be to enslave the VF driver
>>> >> > > netdev under a persistent anchor netdev.
>>> >> > > And it's indeed desired to allow (but not enforce) PV netdev and VF
>>> >> > > netdev to work in conjunction.
>>> >> > > And it's indeed desired that this enslavement logic work out-of-the box.
>>> >> > > But in case of PV+VF some configurable policies must be in place (and
>>> >> > > they'd better be generic rather than differ per PV technology).
>>> >> > > For example - based on which characteristics should the PV+VF coupling
>>> >> > > be done? netvsc uses MAC address, but that might not always be the
>>> >> > > desire.
>>> >> >
>>> >> > It's a policy but not guest userspace policy.
>>> >> >
>>> >> > The hypervisor certainly knows.
>>> >> >
>>> >> > Are you concerned that someone might want to create two devices with the
>>> >> > same MAC for an unrelated reason?  If so, hypervisor could easily set a
>>> >> > flag in the virtio device to say "this is a backup, use MAC to find
>>> >> > another device".
>>> >>
>>> >> This is something I was going to suggest: a flag or other configuration on
>>> >> the virtio device to help control how this new feature is used.  I can
>>> >> imagine this might be useful to control from either the hypervisor side or
>>> >> the VM side.
>>> >>
>>> >> The hypervisor might want to (1) disable it (force it off), (2) enable it
>>> >> for VM choice, or (3) force it on for the VM.  In case (2), the VM might be
>>> >> able to chose whether it wants to make use of the feature, or stick with the
>>> >> bonding solution.
>>> >>
>>> >> Either way, the kernel is making a feature available, and the user (VM or
>>> >> hypervisor) is able to control it by selecting the feature based on the
>>> >> policy desired.
>>> >>
>>> >> sln
>>> >
>>> > I'm not sure what's the feature that is available here.
>>> >
>>> > I saw this as a flag that says "this device shares backend with another
>>> > network device which can be found using MAC, and that backend should be
>>> > preferred".  kernel then forces configuration which uses that other
>>> > backend - as long as it exists.
>>> >
>>> > However, please Cc virtio-dev mailing list if we are doing this since
>>> > this is a spec extension.
>>> >
>>> > --
>>> > MST
>>>
>>>
>>> Can someone please explain why assume a virtio device is there at all??
>>> I specified a case where there isn't any.

Migrating without any virtual device is going to be extremely
challenging, especially in any kind of virtualization setup where the
hosts are not homogeneous. By providing a virtio interface you can
guarantee that at least 1 network interface is available on any given
host, and then fail over to that as the least common denominator for
any migration.

>>> I second Jacob - having a netdev of one device driver enslave a netdev
>>> of another device driver is an awkward a-symmetric model.
>>> Regardless of whether they share the same backend device.
>>> Only I am not sure the Linux Bond is the right choice.
>>> e.g one may well want to use the virtio device also when the
>>> pass-through device is available, e.g for multicasts, east-west
>>> traffic, etc.
>>> I'm not sure the Linux Bond fits that functionality.
>>> And, as I hear in this thread, it is hard to make it work out of the box.
>>> So I think the right thing would be to write a new dedicated module
>>> for this purpose.

This part I can sort of agree with. What if we were to look at
providing a way to somehow advertise that the two devices were meant
to be boded for virtualization purposes? For now lets call it a
"virt-bond". Basically we could look at providing a means for virtio
and VF drivers to advertise that they want this sort of bond. Then it
would just be a matter of providing some sort of side channel to
indicate where you want things like multicast/broadcast/east-west
traffic to go.

>>> Re policy -
>>> Indeed the HV can request a policy from the guest but that's not a
>>> claim for the virtio device enslaving the pass-through device.
>>> Any policy can be queried by the upper enslaving device.
>>>
>>> Bottom line - I do not see a single reason to have the virtio netdev
>>> (nor netvsc or any other PV netdev) enslave another netdev by itself.
>>> If we'd do it right with netvsc from the beginning we wouldn't need
>>> this discussion at all...
>>
>> There are several issues with transparent migration.
>> The first is that the SR-IOV device needs to be shut off for earlier
>> in the migration process.
>
> That's not a given fact.
> It's due to the DMA and it should be solve anyway.
> Please read my first reply in this thread.

For now it is a fact. We would need to do a drastic rewrite of the DMA
API in the guest/host/QEMU/IOMMU in order to avoid it for now. So as a
first step I would say we should look at using this bonding type
solution. Being able to defer the VF eviction could be a next step for
all this as it would allow for much better performance, but we still
have too many cases where the VF might not be there after a migration.

>> Next, the SR-IOV device in the migrated go guest environment maybe different.
>> It might not exist at all, it might be at a different PCI address, or it
>> could even be a different vendor/speed/model.
>> Keeping a virtual network device around allows persisting the connectivity,
>> during the process.
>
> Right, but that virtual device must not relate to any para-virt
> specific technology (not netvsc, nor virtio).
> Again, it seems you did not read my first reply.

I would agree with the need to make this agnostic. Maybe we could look
at the current netvsc solution and find a way to make it generic so it
could be applied to any combination of paravirtual interface and PF.

^ permalink raw reply

* Re: [PATCH net-next 1/4] net: Introduce NETIF_F_GRO_HW
From: Or Gerlitz @ 2017-12-04 16:30 UTC (permalink / raw)
  To: Michael Chan
  Cc: David Miller, Linux Netdev List, Ariel Elior, everest-linux-l2
In-Reply-To: <1512385967-32339-2-git-send-email-michael.chan@broadcom.com>

On Mon, Dec 4, 2017 at 1:12 PM, Michael Chan <michael.chan@broadcom.com> wrote:
> Introduce NETIF_F_GRO_HW feature flag for NICs that support hardware GRO.  W

cool

> --- a/Documentation/networking/netdev-features.txt
> +++ b/Documentation/networking/netdev-features.txt
> @@ -163,3 +163,10 @@ This requests that the NIC receive all possible frames, including errored
>  frames (such as bad FCS, etc).  This can be helpful when sniffing a link with
>  bad packets on it.  Some NICs may receive more packets if also put into normal
>  PROMISC mode.
> +
> +*  rx-gro-hw
> +
> +This requests that the NIC enables Hardware GRO (generic receive offload).
> +Hardware GRO is basically the exact reverse of TSO, and is generally
> +stricter than Hardware LRO.  A packet stream merged by Hardware GRO must
> +be re-segmentable by GSO or TSO back to the exact packet stream.

Can you please add here a 1-2 liner with the grocery store list of requirements
for that matter or pointer to another kernel doc spot where this is defined.

^ permalink raw reply

* Re: Linux 4.14 - regression: broken tun/tap / bridge network with virtio - bisected
From: Andreas Hartmann @ 2017-12-04 16:28 UTC (permalink / raw)
  To: Andreas Hartmann, netdev; +Cc: john.fastabend, Michal Kubecek
In-Reply-To: <4efbaf24-f419-2c8e-c705-59a5242b0575@01019freenet.de>

On 12/03/2017 at 12:35 PM Andreas Hartmann wrote:
> On 12/01/2017 at 11:11 AM Andreas Hartmann wrote:
>> Hello!
>>
>> I hopefully could get rid of both of my problems (hanging network w/
>> virtio) and endless hanging qemu-process on VM shutdown by upgrading
>> qemu from 2.6.2 to 2.10.1. I hope it will persist.
> 
> It didn't persist. 10h later - same problems happened again. It's just
> much harder to trigger the problems.
> 
> I'm now trying it with
> 
> CONFIG_RCU_NOCB_CPU=y and
> rcu_nocbs=0-15
> 
> Since then, I didn't see any problem any more. But this doesn't mean
> anything until now ... .

Didn't work ether. Disabling vhost_net's zcopy hadn't any effect, too.

=> It's just finally broken since

2ddf71e23cc246e95af72a6deed67b4a50a7b81c
net: add notifier hooks for devmap bpf map

Here is the same problem:
https://bugzilla.kernel.org/show_bug.cgi?id=197861

Any idea how to proceed?


Thanks,
Andreas

^ permalink raw reply

* Re: [PATCH] leds: trigger: Introduce a NETDEV trigger
From: Ben Whitten @ 2017-12-04 16:25 UTC (permalink / raw)
  To: Jacek Anaszewski; +Cc: rpurdie, pavel, linux-leds, linux-kernel, netdev
In-Reply-To: <fdc16216-4acc-b87b-1d75-6db33c3fb389@gmail.com>

Hi Jacek,

Thank you for the review, trimmed and comments inline.

On 3 December 2017 at 21:09, Jacek Anaszewski
<jacek.anaszewski@gmail.com> wrote:
>> + * link -  LED's normal state reflects whether the link is up
>> + *         (has carrier) or not
>> + * tx -  LED blinks on transmitted data
>> + * rx -  LED blinks on receive data
>> + *
>> + */
>> +
>> +struct led_netdev_data {
>> +     spinlock_t lock;
>> +
>> +     struct delayed_work work;
>> +     struct notifier_block notifier;
>> +
>> +     struct led_classdev *led_cdev;
>> +     struct net_device *net_dev;
>> +
>> +     char device_name[IFNAMSIZ];
>> +     atomic_t interval;
>> +     unsigned int last_activity;
>> +
>> +     unsigned long mode;
>> +#define LED_BLINK_link       0
>> +#define LED_BLINK_tx 1
>> +#define LED_BLINK_rx 2
>
> LED core already has LED_BLINK* family of macros. Please come up
> with the prefix specific for this trigger e.g. NETDEV_LED.
> Also let's use uppercase for the whole macro name.
>
>> +#define LED_MODE_LINKUP      3
>
> s/LED/NETDEV_LED/
>

Sorted.

>> +};
>> +
>> +static void set_baseline_state(struct led_netdev_data *trigger_data)
>> +{
>> +     if (!test_bit(LED_MODE_LINKUP, &trigger_data->mode))
>> +             led_set_brightness(trigger_data->led_cdev, LED_OFF);
>> +     else {
>> +             if (test_bit(LED_BLINK_link, &trigger_data->mode))
>> +                     led_set_brightness(trigger_data->led_cdev, LED_FULL);
>> +
>> +             if (test_bit(LED_BLINK_tx, &trigger_data->mode) ||
>> +                 test_bit(LED_BLINK_rx, &trigger_data->mode))
>> +                     schedule_delayed_work(&trigger_data->work,
>> +                             atomic_read(&trigger_data->interval));
>
> Now we have blink support in the LED core. Please use
> led_blink_set_oneshot() instead.
>
> Generally you can compare how ledtrig-timer is now implemented.
>

I have cleaned up and converted to led_blink_set_oneshot in the work function
as suggested however it doesn't quite 'look' right yet. So there is something
wrong with my implementation.

When setting blink on RX then initiating a download I find these differences:
Old mechanism, an 'interval' setting of 50ms results in a 100ms period with
50% duty cycle, 50ms on 50ms off.
New mechanism, an 'interval' setting of 10ms resulting in 110ms period with
18% duty cycle, 20ms on 90ms off. Appears to be quite a delay getting the
blink queued up again.

The oneshot is set in the worker function tasked with gathering netdev stats.
I'll keep exploring.

>> +#define led_mode_flags_attr(field)                                   \
>> +static ssize_t field##_show(struct device *dev,                              \
>> +     struct device_attribute *attr, char *buf)                       \
>> +{                                                                    \
>> +     struct led_classdev *led_cdev = dev_get_drvdata(dev);           \
>> +     struct led_netdev_data *trigger_data = led_cdev->trigger_data;  \
>> +                                                                     \
>> +     return sprintf(buf, "%u\n", test_bit(LED_BLINK_##field,         \
>> +                                     &trigger_data->mode));          \
>> +}                                                                    \
>> +static ssize_t field##_store(struct device *dev,                     \
>> +     struct device_attribute *attr, const char *buf, size_t size)    \
>> +{                                                                    \
>> +     struct led_classdev *led_cdev = dev_get_drvdata(dev);           \
>> +     struct led_netdev_data *trigger_data = led_cdev->trigger_data;  \
>> +     unsigned long state;                                            \
>> +     int ret;                                                        \
>> +                                                                     \
>> +     ret = kstrtoul(buf, 0, &state);                                 \
>> +     if (ret)                                                        \
>> +             return ret;                                             \
>> +                                                                     \
>> +     cancel_delayed_work_sync(&trigger_data->work);                  \
>> +                                                                     \
>> +     if (state)                                                      \
>> +             set_bit(LED_BLINK_##field, &trigger_data->mode);        \
>> +     else                                                            \
>> +             clear_bit(LED_BLINK_##field, &trigger_data->mode);      \
>> +                                                                     \
>> +     set_baseline_state(trigger_data);                               \
>> +                                                                     \
>> +     return size;                                                    \
>> +}                                                                    \
>> +static DEVICE_ATTR_RW(field);
>
> In order to get rid of this macro and avoid the need for camel case
> macro name we could have one function that would accept an enum e.g.
>
> enum netdev_led_attr {
>         NETDEV_ATTR_LINK,
>         NETDEV_ATTR_RX,
>         NETDEV_ATTR_TX
> };
>
> The function would be called from each sysfs attr callback with the
> related enum, and would alter the state of the related bit.
>

I was aiming for a bit of code de duplication, but it ended up a mess.
Fixed as per your suggestion.

^ permalink raw reply

* Re: [PATCH 03/10] net: ezchip: nps_enet: Fix platform_get_irq's error checking
From: Russell King - ARM Linux @ 2017-12-04 16:24 UTC (permalink / raw)
  To: David Miller
  Cc: arvind.yadav.cs, f.fainelli, netdev, michal.simek, linux-kernel,
	opendmb, mkl, linux-arm-kernel, Vladislav.Zakharov, wg
In-Reply-To: <20171204.112049.2189145622743900344.davem@davemloft.net>

On Mon, Dec 04, 2017 at 11:20:49AM -0500, David Miller wrote:
> From: Arvind Yadav <arvind.yadav.cs@gmail.com>
> Date: Sun,  3 Dec 2017 00:56:15 +0530
> 
> > The platform_get_irq() function returns negative if an error occurs.
> > zero or positive number on success. platform_get_irq() error checking
> > for zero is not correct. And remove unnecessary check for free_netdev().
> > 
> > Signed-off-by: Arvind Yadav <arvind.yadav.cs@gmail.com>
> > ---
> >  drivers/net/ethernet/ezchip/nps_enet.c | 7 +++----
> >  1 file changed, 3 insertions(+), 4 deletions(-)
> > 
> > diff --git a/drivers/net/ethernet/ezchip/nps_enet.c b/drivers/net/ethernet/ezchip/nps_enet.c
> > index 659f1ad..82dc6d0 100644
> > --- a/drivers/net/ethernet/ezchip/nps_enet.c
> > +++ b/drivers/net/ethernet/ezchip/nps_enet.c
> > @@ -623,9 +623,9 @@ static s32 nps_enet_probe(struct platform_device *pdev)
> >  
> >  	/* Get IRQ number */
> >  	priv->irq = platform_get_irq(pdev, 0);
> > -	if (!priv->irq) {
> > +	if (priv->irq <= 0) {
> >  		dev_err(dev, "failed to retrieve <irq Rx-Tx> value from device tree\n");
> > -		err = -ENODEV;
> > +		err = priv->irq ? priv->irq : -ENODEV;
> 
> If platform_get_irq() returns "zero or positive number on success" then this
> test is wrong and should be "if (priv->irq < 0)"
> 
> Also, this series is a mix of different kinds of changes.
> 
> Please separate out the platform IRQ error checking and just submit exactly
> those changes as a patch series.
> 
> The other bug fixes should be submitted outside of those changes since they
> are unrelated.

The issue of whether IRQ 0 is valid or not has been covered several times
by Linus, and the result is that it is deemed by Linus that IRQ 0 is not
a valid interrupt.

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line in suburbia: sync at 8.8Mbps down 630kbps up
According to speedtest.net: 8.21Mbps down 510kbps up

^ permalink raw reply

* Re: [PATCH 03/10] net: ezchip: nps_enet: Fix platform_get_irq's error checking
From: David Miller @ 2017-12-04 16:20 UTC (permalink / raw)
  To: arvind.yadav.cs
  Cc: wg, mkl, michal.simek, opendmb, f.fainelli, Vladislav.Zakharov,
	linux-kernel, linux-arm-kernel, netdev
In-Reply-To: <1512242782-7134-4-git-send-email-arvind.yadav.cs@gmail.com>

From: Arvind Yadav <arvind.yadav.cs@gmail.com>
Date: Sun,  3 Dec 2017 00:56:15 +0530

> The platform_get_irq() function returns negative if an error occurs.
> zero or positive number on success. platform_get_irq() error checking
> for zero is not correct. And remove unnecessary check for free_netdev().
> 
> Signed-off-by: Arvind Yadav <arvind.yadav.cs@gmail.com>
> ---
>  drivers/net/ethernet/ezchip/nps_enet.c | 7 +++----
>  1 file changed, 3 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/net/ethernet/ezchip/nps_enet.c b/drivers/net/ethernet/ezchip/nps_enet.c
> index 659f1ad..82dc6d0 100644
> --- a/drivers/net/ethernet/ezchip/nps_enet.c
> +++ b/drivers/net/ethernet/ezchip/nps_enet.c
> @@ -623,9 +623,9 @@ static s32 nps_enet_probe(struct platform_device *pdev)
>  
>  	/* Get IRQ number */
>  	priv->irq = platform_get_irq(pdev, 0);
> -	if (!priv->irq) {
> +	if (priv->irq <= 0) {
>  		dev_err(dev, "failed to retrieve <irq Rx-Tx> value from device tree\n");
> -		err = -ENODEV;
> +		err = priv->irq ? priv->irq : -ENODEV;

If platform_get_irq() returns "zero or positive number on success" then this
test is wrong and should be "if (priv->irq < 0)"

Also, this series is a mix of different kinds of changes.

Please separate out the platform IRQ error checking and just submit exactly
those changes as a patch series.

The other bug fixes should be submitted outside of those changes since they
are unrelated.

^ permalink raw reply

* Re: [PATCH v4.1] phylib: Add device reset GPIO support
From: Richard Leitner @ 2017-12-04 16:20 UTC (permalink / raw)
  To: Geert Uytterhoeven, David S . Miller, Andrew Lunn,
	Florian Fainelli, Simon Horman, Magnus Damm
  Cc: Sergei Shtylyov, Rob Herring, Mark Rutland, Nicolas Ferre, netdev,
	devicetree, linux-renesas-soc, linux-kernel
In-Reply-To: <1512390905-28094-1-git-send-email-geert+renesas@glider.be>


On 12/04/2017 01:35 PM, Geert Uytterhoeven wrote:
> From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
> 
> The PHY devices sometimes do have their reset signal (maybe even power
> supply?) tied to some GPIO and sometimes it also does happen that a boot
> loader does not leave it deasserted. So far this issue has been attacked
> from (as I believe) a wrong angle: by teaching the MAC driver to manipulate
> the GPIO in question; that solution, when applied to the device trees, led
> to adding the PHY reset GPIO properties to the MAC device node, with one
> exception: Cadence MACB driver which could handle the "reset-gpios" prop
> in a PHY device subnode. I believe that the correct approach is to teach
> the 'phylib' to get the MDIO device reset GPIO from the device tree node
> corresponding to this device -- which this patch is doing...
> 
> Note that I had to modify the AT803x PHY driver as it would stop working
> otherwise -- it made use of the reset GPIO for its own purposes...
> 
> Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
> Acked-by: Rob Herring <robh@kernel.org>
> [geert: Propagate actual errors from fwnode_get_named_gpiod()]
> [geert: Avoid destroying initial setup]
> [geert: Consolidate GPIO descriptor acquiring code]
> Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
> ---

Successfully tested this patch on a i.MX6SOLO based board containing a
LAN8710 PHY:

Tested-by: Richard Leitner <richard.leitner@skidata.com>

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox