* Re: [v5, PATCH 1/2] net:stmmac: dwmac-mediatek: add support for mt2712
From: biao huang @ 2018-11-23 9:09 UTC (permalink / raw)
To: Sean Wang
Cc: davem, robh+dt, mark.rutland, devicetree, nelson.chang,
Andrew Lunn, netdev, Liguo Zhang, linux-kernel, Matthias Brugger,
joabreu, linux-mediatek, honghui.zhang, linux-arm-kernel
In-Reply-To: <CAGp9LzrdwXqQ+aHtCoKcxKx28xR21hKnpc+ruW4Gt7TyQLffsA@mail.gmail.com>
Dear Sean,
Thanks for your comments.
If any misunderstanding, please correct me.
On Thu, 2018-11-22 at 23:04 -0800, Sean Wang wrote:
> < ... >
>
> > > > + /* select phy interface in top control domain */
> > > > + switch (plat->phy_mode) {
> > > > + case PHY_INTERFACE_MODE_MII:
> > > > + intf_val |= PHY_INTF_MII_GMII;
> > > > + break;
> > > > + case PHY_INTERFACE_MODE_RMII:
> > > > + intf_val |= PHY_INTF_RMII;
> > > > + intf_val |= rmii_rxc;
> > > how about putting into one line such as intf_val |= (PHY_INTF_RMII | rmii_rxc) ?
> > >
> > ok, will change in next version.
> > > > + break;
> > > > + case PHY_INTERFACE_MODE_RGMII:
> > > > + case PHY_INTERFACE_MODE_RGMII_TXID:
> > > > + case PHY_INTERFACE_MODE_RGMII_RXID:
> > > > + case PHY_INTERFACE_MODE_RGMII_ID:
> > > > + intf_val |= PHY_INTF_RGMII;
> > > > + break;
> > > > + default:
> > > > + dev_err(plat->dev, "phy interface not supported\n");
> > > > + return -EINVAL;
> > > > + }
> > > > +
> > > > + regmap_write(plat->peri_regmap, PERI_ETH_PHY_INTF_SEL, intf_val);
> > > > +
> > > > + return 0;
> > > > +}
> > > > +
> > > > +static int mt2712_set_delay(struct mediatek_dwmac_plat_data *plat)
> > > > +{
> > > > + struct mac_delay_struct *mac_delay = &plat->mac_delay;
> > > > + u32 delay_val = 0;
> > > > + u32 fine_val = 0;
> > > The same type declaration can be put into the one line
> > >
> > Got it.
> > > > +
> > > > + switch (plat->phy_mode) {
> > >
> > > There exists some room for code optimization in the switch statement
> > > such as PHY_INTERFACE_MODE_MII and PHY_INTERFACE_MODE_RGMII both are
> > > almost the same and even the configuration for the other PHY modes can
> > > reuse their partial setup. It appears to be better using a common way
> > > to set up various PHY modes.
> > >
> > I'll try define a function to handle it.
> > And how about like this:
> > static u32 delay_setting(u32 delay, bool inv, u32 en_bit, u32
> > clk_shift, u32 clk_mask, u32 inv_bit) {
> > u32 value = 0
> >
> > value |= delay ? en_bit : 0;
> > value |= (delay << clk_shift) & clk_mask;
> > value |= inv ? inv_bit : 0;
> > }
> >
> > case PHY_INTERFACE_MODE_MII:
> > delay_value |= delay_setting(mac_delay->tx_delay,
> > mac_delay->tx_inv,
> > PHY_DLY_TXC_ENABLE,
> > PHY_DLY_TXC_SHIFT,
> > PHY_DLY_TXC_STAGES,
> > PHY_DLY_TXC_INV);
>
> We can reuse FIELD_PREP defined in include/linux/bitfield.h to make up
> of the value instead of creating your own function delay_setting here,
> and also PHY_DLY_TXC_SHIFT macro can be trimmed while you're using
> FIED_PREP
>
ok, so it should like this:
delay_value |= FIELD_PREP(PHY_DLY_TXC_ENABLE, !!mac_delay->delay);
delay_value |= FIELD_PREP(PHY_DLY_TXC_STAGES, mac_delay->delay);
delay_value |= FIELD_PREP(PHY_DLY_TXC_INV, mac_delay->inv);
> > delay_value |= delay_setting(mac_delay->rx_delay,
> > mac_delay->rx_inv,
> > PHY_DLY_RXC_ENABLE,
> > PHY_DLY_RXC_SHIFT,
> > PHY_DLY_RXC_STAGES,
> > PHY_DLY_RXC_INV);
> >
> > case PHY_INTERFACE_MODE_RMII:
> > if (plat->rmii_rxc) {
> > delay_value |= delay_setting(mac_delay->rx_delay,
> > mac_delay->rx_inv,
> > PHY_DLY_RXC_ENABLE,
> > PHY_DLY_RXC_SHIFT,
> > PHY_DLY_RXC_STAGES,
> > PHY_DLY_RXC_INV);
> > fine_val |= mac_delay->tx_inv ?
> > ETH_RMII_DLY_TX_INV : 0;
> > } else {
> > delay_value |= delay_setting(mac_delay->rx_delay,
> > mac_delay->rx_inv,
>
> shoudn't the parametors be mac_delay->tx_delay and mac_delay->tx_inv?
>
in this case, the rmii reference clk from external phy is connected to
TXC pin, and property "rmii_rxc" will handle which pin the reference clk
is connected to. after that, the reference clk is only a received clk
from outside, so use rx_delay/rx_inv may be much better.
> > PHY_DLY_TXC_ENABLE,
> > PHY_DLY_TXC_SHIFT,
> > PHY_DLY_TXC_STAGES,
> > PHY_DLY_TXC_INV);
> > fine_val |= mac_delay->tx_inv ?
> > ETH_RMII_DLY_TX_INV : 0;
>
> if (plat->tx_inv)
> fine_val = ETH_RMII_DLY_TX_INV;
> the default fine_val is zero so zero assignement can be trimmed when
> !plat-> tx_inv
>
> > }
> > case PHY_INTERFACE_MODE_RGMII:
> > fine_val = plat->fine_tune ?
> > (ETH_FINE_DLY_GTXC | ETH_FINE_DLY_RXC) : 0;
>
> if (plat->fine_tune)
> fine_val = ETH_FINE_DLY_GTXC | ETH_FINE_DLY_RXC;
> the default fine_val is zero so zero assignement can be trimmed when
> !plat->fine_tune
>
ok, I'll not initialize fine_val.
> > delay_value |= delay_setting(mac_delay->tx_delay,
> > mac_delay->tx_inv,
> > PHY_DLY_GTXC_ENABLE,
> > PHY_DLY_GTXC_SHIFT,
> > PHY_DLY_GTXC_STAGES,
> > PHY_DLY_GTXC_INV);
> > delay_value |= delay_setting(mac_delay->rx_delay,
> > mac_delay->rx_inv,
> > PHY_DLY_RXC_ENABLE,
> > PHY_DLY_RXC_SHIFT,
> > PHY_DLY_RXC_STAGES,
> > PHY_DLY_RXC_INV);
> > case PHY_INTERFACE_MODE_RGMII_TXID:
> > fine_val = plat->fine_tune ? ETH_FINE_DLY_RXC : 0;
> > delay_value |= delay_setting(mac_delay->rx_delay,
> > mac_delay->rx_inv,
> > PHY_DLY_RXC_ENABLE,
> > PHY_DLY_RXC_SHIFT,
> > PHY_DLY_RXC_STAGES,
> > PHY_DLY_RXC_INV);
> > case PHY_INTERFACE_MODE_RGMII_RXID:
> > fine_val = plat->fine_tune ? ETH_FINE_DLY_GTXC : 0;
> > delay_value |= delay_setting(mac_delay->tx_delay,
> > mac_delay->tx_inv,
> > PHY_DLY_GTXC_ENABLE,
> > PHY_DLY_GTXC_SHIFT,
> > PHY_DLY_GTXC_STAGES,
> > PHY_DLY_GTXC_INV);
> >
>
> phy_mode is used to indicate what phy mode would be tweaked when mac
> is connected to the phy so I thought mac delay can be independent from
> phy internal delay that means PHY_INTERFACE_MODE_RGMII_RXID and
> PHY_INTERFACE_MODE_RGMII_TXID can apply the same setting as
> PHY_INTERFACE_MODE_RGMII does.
>
no, when phy adjust the tx delay, mac should not adjust tx delay at the
same time. ex: phy will delay 2ns, and mac delay 2ns, the total delay
will be 2+2=4ns.the whole delay will not meet the rgmii requirement.
And PHY_INTERFACE_MODE_RGMII_TXID/RXID/ID is clarified clearly in
phy.txt, I think it should be ok here.
More, I'll add comments here to avoid confusion.
> > > > + case PHY_INTERFACE_MODE_MII:
> > > > + delay_val |= mac_delay->tx_delay ? PHY_DLY_TXC_ENABLE : 0;
> > > > + delay_val |= (mac_delay->tx_delay << PHY_DLY_TXC_SHIFT) &
> > > > + PHY_DLY_TXC_STAGES;
> > > > + delay_val |= mac_delay->tx_inv ? PHY_DLY_TXC_INV : 0;
> > > > + delay_val |= mac_delay->rx_delay ? PHY_DLY_RXC_ENABLE : 0;
> > > > + delay_val |= (mac_delay->rx_delay << PHY_DLY_RXC_SHIFT) &
> > > > + PHY_DLY_RXC_STAGES;
> > > > + delay_val |= mac_delay->rx_inv ? PHY_DLY_RXC_INV : 0;
> > > > + break;
> > > > + case PHY_INTERFACE_MODE_RMII:
> > > > + if (plat->rmii_rxc) {
> > > > + delay_val |= mac_delay->rx_delay ?
> > > > + PHY_DLY_RXC_ENABLE : 0;
> > > > + delay_val |= (mac_delay->rx_delay <<
> > > > + PHY_DLY_RXC_SHIFT) & PHY_DLY_RXC_STAGES;
> > > > + delay_val |= mac_delay->rx_inv ? PHY_DLY_RXC_INV : 0;
> > > > + fine_val |= mac_delay->tx_inv ?
> > > > + ETH_RMII_DLY_TX_INV : 0;
> > > why is fine_val got from tx_inv?
> > >
> > becase the tx inv will inverse the tx clock inside mac relative to
> > reference clock from external phy, and this bit is located in the same
> > register with fine-tune.
> > maybe I should rename fine_val to avoid misunderstanding.
>
> If you add more comments to say that, fine_val remains would be okay
>
OK, I'll add comments.
> > > > + } else {
> > > > + delay_val |= mac_delay->rx_delay ?
> > > > + PHY_DLY_TXC_ENABLE : 0;
> > > > + delay_val |= (mac_delay->rx_delay <<
> > > > + PHY_DLY_TXC_SHIFT) & PHY_DLY_TXC_STAGES;
> > > > + delay_val |= mac_delay->rx_inv ? PHY_DLY_TXC_INV : 0;
> > > > + fine_val |= mac_delay->tx_inv ?
> > > > + ETH_RMII_DLY_TX_INV : 0;
> > > ditto, why is fine_val got from tx_inv?
> > >
> > same as above. ETH_RMII_DLY_TX_INV is only for RMII, and located in the
> > same register with fine-tune.
>
> adding a fewer comments helps to avoid some confusion
>
OK.
> > > > + }
> > > > + break;
> > > > + case PHY_INTERFACE_MODE_RGMII:
> > > > + fine_val = plat->fine_tune ?
> > > > + (ETH_FINE_DLY_GTXC | ETH_FINE_DLY_RXC) : 0;
> > > > + delay_val |= mac_delay->tx_delay ? PHY_DLY_GTXC_ENABLE : 0;
> > > > + delay_val |= mac_delay->tx_delay & PHY_DLY_GTXC_STAGES;
> > > > + delay_val |= mac_delay->tx_inv ? PHY_DLY_GTXC_INV : 0;
> > > > + delay_val |= mac_delay->rx_delay ? PHY_DLY_RXC_ENABLE : 0;
> > > > + delay_val |= (mac_delay->rx_delay << PHY_DLY_RXC_SHIFT) &
> > > > + PHY_DLY_RXC_STAGES;
> > > > + delay_val |= mac_delay->rx_inv ? PHY_DLY_RXC_INV : 0;
> > > > + break;
> > > > + case PHY_INTERFACE_MODE_RGMII_TXID:
> > > > + fine_val = plat->fine_tune ? ETH_FINE_DLY_RXC : 0;
> > > > + delay_val |= mac_delay->rx_delay ? PHY_DLY_RXC_ENABLE : 0;
> > > > + delay_val |= (mac_delay->rx_delay << PHY_DLY_RXC_SHIFT) &
> > > > + PHY_DLY_RXC_STAGES;
> > > > + delay_val |= mac_delay->rx_inv ? PHY_DLY_RXC_INV : 0;
> > > why is PHY_INTERFACE_MODE_RGMII_TXID applied with *_RXC_* register
> > > bits, not with *_TXC_* bits? I'm a little confused about what path the
> > > register PHY_DLY_RXC_* cause the effects to? MAC to PHY or PHY to MAC?
> > >
> > The PHY_INTERFACE_MODE_RGMII_TXID is defined in
> > Documentation/networking/phy.txt
> > means phy will handle delay in tx path, so mac need handle delay in rx
> > path here.
>
> See the above explains: phy_mode is used to indicate what phy mode
> would be tweaked when mac is connected to the phy so I thought mac
> delay can be independent of phy internal delay that means
> PHY_INTERFACE_MODE_RGMII_RXID and PHY_INTERFACE_MODE_RGMII_TXID can
> apply the same setting as PHY_INTERFACE_MODE_RGMII does.
>
Maybe more comments will avoid confusion.
> > > > + break;
> > > > + case PHY_INTERFACE_MODE_RGMII_RXID:
> > > > + fine_val = plat->fine_tune ? ETH_FINE_DLY_GTXC : 0;
> > > > + delay_val |= mac_delay->tx_delay ? PHY_DLY_GTXC_ENABLE : 0;
> > > > + delay_val |= mac_delay->tx_delay & PHY_DLY_GTXC_STAGES;
> > > > + delay_val |= mac_delay->tx_inv ? PHY_DLY_GTXC_INV : 0;
> > > ditto, as the above quetion
> > >
> > Similar answer as above.
> > > > + break;
> > > > + case PHY_INTERFACE_MODE_RGMII_ID:
> > > > + break;
> > > > + default:
> > > > + dev_err(plat->dev, "phy interface not supported\n");
> > > > + return -EINVAL;
> > > > + }
> > > > + regmap_write(plat->peri_regmap, PERI_ETH_PHY_DLY, delay_val);
> > > > + regmap_write(plat->peri_regmap, PERI_ETH_DLY_FINE, fine_val);
> > > > +
> > > > + return 0;
> > > > +}
> > > > +
> > > > +static const struct mediatek_dwmac_variant mt2712_gmac_variant = {
> > > > + .dwmac_set_phy_interface = mt2712_set_interface,
> > > > + .dwmac_set_delay = mt2712_set_delay,
> > > > + .clk_list = mt2712_dwmac_clk_l,
> > > > + .num_clks = ARRAY_SIZE(mt2712_dwmac_clk_l),
> > > > + .dma_bit_mask = 33,
> > > > + .rx_delay_max = 32,
> > > > + .tx_delay_max = 32,
> > > > +};
> > > > +
> > > > +static int mediatek_dwmac_config_dt(struct mediatek_dwmac_plat_data *plat)
> > > > +{
> > > > + u32 tx_delay, rx_delay;
> > > > +
> > > > + plat->peri_regmap = syscon_regmap_lookup_by_phandle(plat->np, "mediatek,pericfg");
>
> you're also missing the property definition in dt-binding.
>
thanks for remind. I'll add in next patch.
> > > > + if (IS_ERR(plat->peri_regmap)) {
> > > > + dev_err(plat->dev, "Failed to get pericfg syscon\n");
> > > > + return PTR_ERR(plat->peri_regmap);
> > > > + }
> > > > +
> > > > + plat->phy_mode = of_get_phy_mode(plat->np);
> > > > + if (plat->phy_mode < 0) {
> > > > + dev_err(plat->dev, "not find phy-mode\n");
> > > > + return -EINVAL;
> > > > + }
> > > > +
> > > > + if (!of_property_read_u32(plat->np, "mediatek,tx-delay", &tx_delay)) {
> > > > + if (tx_delay < plat->variant->tx_delay_max) {
> > > > + plat->mac_delay.tx_delay = tx_delay;
> > > > + } else {
> > > > + dev_err(plat->dev, "Invalid TX clock delay: %d\n", tx_delay);
> > > > + return -EINVAL;
> > > > + }
> > > > + }
> > > > +
> > > > + if (!of_property_read_u32(plat->np, "mediatek,rx-delay", &rx_delay)) {
> > > > + if (rx_delay < plat->variant->rx_delay_max) {
> > > > + plat->mac_delay.rx_delay = rx_delay;
> > > > + } else {
> > > > + dev_err(plat->dev, "Invalid RX clock delay: %d\n", rx_delay);
> > > > + return -EINVAL;
> > > > + }
> > > > + }
> > > > +
> > > > + plat->mac_delay.tx_inv = of_property_read_bool(plat->np, "mediatek,txc-inverse");
> > > > + plat->mac_delay.rx_inv = of_property_read_bool(plat->np, "mediatek,rxc-inverse");
> > > > + plat->fine_tune = of_property_read_bool(plat->np, "mediatek,fine-tune");
> > > > + plat->rmii_rxc = of_property_read_bool(plat->np, "mediatek,rmii-rxc");
> > > > +
> > > > + return 0;
> > > > +}
> > > > +
> > > > +static int mediatek_dwmac_clk_init(struct mediatek_dwmac_plat_data *plat)
> > > > +{
> > > > + const struct mediatek_dwmac_variant *variant = plat->variant;
> > > > + int num = variant->num_clks;
> > > > + int i;
> > > put into the same line seems good
> > >
> > ok
> > > > +
> > > > + plat->clks = devm_kcalloc(plat->dev, num, sizeof(*plat->clks), GFP_KERNEL);
> > > > + if (!plat->clks)
> > > > + return -ENOMEM;
> > > > +
> > > > + for (i = 0; i < num; i++)
> > > > + plat->clks[i].id = variant->clk_list[i];
> > > > +
> > > > + return devm_clk_bulk_get(plat->dev, num, plat->clks);
> > > > +}
> > > > +
> > > > +static int mediatek_dwmac_init(struct platform_device *pdev, void *priv)
> > > > +{
> > > > + struct mediatek_dwmac_plat_data *plat = priv;
> > > > + const struct mediatek_dwmac_variant *variant = plat->variant;
> > > > + int ret = 0;
> > > zero initialized seems unnecessary
> > >
> > ok, will not initialized here
> > > > +
> > > > + ret = dma_set_mask_and_coherent(plat->dev, DMA_BIT_MASK(variant->dma_bit_mask));
> > > > + if (ret) {
> > > > + dev_err(plat->dev, "No suitable DMA available, err = %d\n", ret);
> > > > + return ret;
> > > > + }
> > > > +
> > > > + ret = variant->dwmac_set_phy_interface(plat);
> > > > + if (ret) {
> > > > + dev_err(plat->dev, "failed to set phy interface, err = %d\n", ret);
> > > > + return ret;
> > > > + }
> > > > +
> > > > + ret = variant->dwmac_set_delay(plat);
> > > > + if (ret) {
> > > > + dev_err(plat->dev, "failed to set delay value, err = %d\n", ret);
> > > > + return ret;
> > > > + }
> > > > +
> > > > + ret = clk_bulk_prepare_enable(variant->num_clks, plat->clks);
> > > > + if (ret) {
> > > > + dev_err(plat->dev, "failed to enable clks, err = %d\n", ret);
> > > > + return ret;
> > > > + }
> > > > +
> > > > + return 0;
> > > > +}
> > > > +
> > > > +static void mediatek_dwmac_exit(struct platform_device *pdev, void *priv)
> > > > +{
> > > > + struct mediatek_dwmac_plat_data *plat = priv;
> > > > + const struct mediatek_dwmac_variant *variant = plat->variant;
> > > > +
> > > > + clk_bulk_disable_unprepare(variant->num_clks, plat->clks);
> > > > +}
> > > > +
> > > > +static int mediatek_dwmac_probe(struct platform_device *pdev)
> > > > +{
> > > > + struct mediatek_dwmac_plat_data *priv_plat;
> > > > + struct plat_stmmacenet_data *plat_dat;
> > > > + struct stmmac_resources stmmac_res;
> > > > + int ret = 0;
> > > zero initialized seems unnecessary
> > >
> > ok, will not initialized here
> > > > +
> > > > + priv_plat = devm_kzalloc(&pdev->dev, sizeof(*priv_plat), GFP_KERNEL);
> > > > + if (!priv_plat)
> > > > + return -ENOMEM;
> > > > +
> > > > + priv_plat->variant = of_device_get_match_data(&pdev->dev);
> > > > + if (!priv_plat->variant) {
> > > > + dev_err(&pdev->dev, "Missing dwmac-mediatek variant\n");
> > > > + return -EINVAL;
> > > > + }
> > > > +
> > > > + priv_plat->dev = &pdev->dev;
> > > > + priv_plat->np = pdev->dev.of_node;
> > > > +
> > > > + ret = mediatek_dwmac_config_dt(priv_plat);
> > > > + if (ret)
> > > > + return ret;
> > > > +
> > > > + ret = mediatek_dwmac_clk_init(priv_plat);
> > > > + if (ret)
> > > > + return ret;
> > > > +
> > > > + ret = stmmac_get_platform_resources(pdev, &stmmac_res);
> > > > + if (ret)
> > > > + return ret;
> > > > +
>
> < ... >
^ permalink raw reply
* Re: [EXT] Re: [PATCH net-next 4/4] octeontx2-af: Bringup CGX LMAC links by default
From: Cherian, Linu @ 2018-11-22 22:46 UTC (permalink / raw)
To: Andrew Lunn
Cc: Linu Cherian, netdev@vger.kernel.org, davem@davemloft.net,
Goutham, Sunil, Linu Cherian
In-Reply-To: <20181122182656.GE10697@lunn.ch>
On Thu Nov 22, 2018 at 07:26:56PM +0100, Andrew Lunn wrote:
> External Email
>
> External Email
>
> ----------------------------------------------------------------------
> On Thu, Nov 22, 2018 at 05:18:37PM +0530, Linu Cherian wrote:
> > From: Linu Cherian <lcherian@marvell.com>
> >
> > - Added new CGX firmware interface API for sending link up/down
> > commands
> >
> > - Do link up for cgx lmac ports by default at the time of CGX
> > driver probe.
>
> Hi Linu
>
> This is a complex driver which i don't understand...
>
> By link up, do you mean the equivalent of 'ip link set up dev ethX'?
Not really. It is used to do the necessary LMAC port hardware configuration
based on the connected PHYs and bringup the the PHY links.
>
> Andrew
--
Linu cherian
^ permalink raw reply
* [PATCH v2 net] phy: Micrel KSZ8061: link failure after cable connect
From: Onnasch, Alexander (EXT) @ 2018-11-23 9:36 UTC (permalink / raw)
Cc: Onnasch, Alexander (EXT), Andrew Lunn, Florian Fainelli,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org
With Micrel KSZ8061 PHY, the link may occasionally not come up after
Ethernet cable connect. The vendor's (Microchip, former Micrel) errata
sheet 80000688A.pdf describes the problem and possible workarounds in
detail, see below.
The patch implements workaround 1, which permanently fixes the issue.
DESCRIPTION
Link-up may not occur properly when the Ethernet cable is initially
connected. This issue occurs more commonly when the cable is connected
slowly, but it may occur any time a cable is connected. This issue occurs
in the auto-negotiation circuit, and will not occur if auto-negotiation
is disabled (which requires that the two link partners be set to the
same speed and duplex).
END USER IMPLICATIONS
When this issue occurs, link is not established. Subsequent cable
plug/unplug cycles will not correct the issue.
WORK AROUND
There are four approaches to work around this issue:
1. This issue can be prevented by setting bit 15 in MMD device address 1,
register 2, prior to connecting the cable or prior to setting the
Restart Auto-Negotiation bit in register 0h.The MMD registers are
accessed via the indirect access registers Dh and Eh, or via the Micrel
EthUtil utility as shown here:
• If using the EthUtil utility (usually with a Micrel KSZ8061
Evaluation Board), type the following commands:
> address 1
> mmd 1
> iw 2 b61a
• Alternatively, write the following registers to write to the
indirect MMD register:
Write register Dh, data 0001h
Write register Eh, data 0002h
Write register Dh, data 4001h
Write register Eh, data B61Ah
2. The issue can be avoided by disabling auto-negotiation in the KSZ8061,
either by the strapping option, or by clearing bit 12 in register 0h.
Care must be taken to ensure that the KSZ8061 and the link partner
will link with the same speed and duplex. Note that the KSZ8061
defaults to full-duplex when auto-negotiation is off, but other
devices may default to half-duplex in the event of failed
auto-negotiation.
3. The issue can be avoided by connecting the cable prior to powering-up
or resetting the KSZ8061, and leaving it plugged in thereafter.
4. If the above measures are not taken and the problem occurs, link can
be recovered by setting the Restart Auto-Negotiation bit in
register 0h, or by resetting or power cycling the device. Reset may
be either hardware reset or software reset (register 0h, bit 15).
PLAN
This errata will not be corrected in a future revision.
Signed-off-by: Alexander Onnasch <alexander.onnasch@landisgyr.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
---
drivers/net/phy/micrel.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
index 6c45ff6..eb85cf4 100644
--- a/drivers/net/phy/micrel.c
+++ b/drivers/net/phy/micrel.c
@@ -339,6 +339,17 @@ static int ksz8041_config_aneg(struct phy_device *phydev)
return genphy_config_aneg(phydev);
}
+static int ksz8061_config_init(struct phy_device *phydev)
+{
+ int ret;
+
+ ret = phy_write_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_DEVID1, 0xB61A);
+ if (ret)
+ return ret;
+
+ return kszphy_config_init(phydev);
+}
+
static int ksz9021_load_values_from_of(struct phy_device *phydev,
const struct device_node *of_node,
u16 reg,
@@ -938,7 +949,7 @@ static struct phy_driver ksphy_driver[] = {
.phy_id_mask = MICREL_PHY_ID_MASK,
.features = PHY_BASIC_FEATURES,
.flags = PHY_HAS_INTERRUPT,
- .config_init = kszphy_config_init,
+ .config_init = ksz8061_config_init,
.config_aneg = genphy_config_aneg,
.read_status = genphy_read_status,
.ack_interrupt = kszphy_ack_interrupt,
--
2.7.4
^ permalink raw reply related
* [PATCH v3 0/2] bpf: permit JIT allocations to be served outside the module region
From: Ard Biesheuvel @ 2018-11-23 9:41 UTC (permalink / raw)
To: linux-kernel
Cc: Ard Biesheuvel, Daniel Borkmann, Alexei Starovoitov,
Rick Edgecombe, Eric Dumazet, Jann Horn, Kees Cook, Jessica Yu,
Arnd Bergmann, Catalin Marinas, Will Deacon, Mark Rutland,
David S. Miller, linux-arm-kernel, netdev
On arm64, modules are allocated from a 128 MB window which is close to
the core kernel, so that relative direct branches are guaranteed to be
in range (except in some KASLR configurations). Also, module_alloc()
is in charge of allocating KASAN shadow memory when running with KASAN
enabled.
This means that the way BPF reuses module_alloc()/module_memfree() is
undesirable on arm64 (and potentially other architectures as well),
and so this series refactors BPF's use of those functions to permit
architectures to change this behavior.
Patch #1 breaks out the module_alloc() and module_memfree() calls into
__weak functions so they can be overridden.
Patch #2 implements the new alloc/free overrides for arm64
Changes since v2:
- properly build time and runtime tested this time (log after the diffstat)
- create a dedicated 128 MB region at the top of the vmalloc space for BPF
programs, ensuring that the programs will be in branching range of each
other (which we currently rely upon) but at an arbitrary distance from
the kernel and modules (which we don't care about)
Changes since v1:
- Drop misguided attempt to 'fix' and refactor the free path. Instead,
just add another __weak wrapper for the invocation of module_memfree()
Cc: Daniel Borkmann <daniel@iogearbox.net>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Rick Edgecombe <rick.p.edgecombe@intel.com>
Cc: Eric Dumazet <eric.dumazet@gmail.com>
Cc: Jann Horn <jannh@google.com>
Cc: Kees Cook <keescook@chromium.org>
Cc: Jessica Yu <jeyu@kernel.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
Cc: netdev@vger.kernel.org
Ard Biesheuvel (2):
bpf: add __weak hook for allocating executable memory
arm64/bpf: don't allocate BPF JIT programs in module memory
arch/arm64/include/asm/memory.h | 3 +++
arch/arm64/include/asm/pgtable.h | 2 +-
arch/arm64/net/bpf_jit_comp.c | 13 +++++++++++++
kernel/bpf/core.c | 14 ++++++++++++--
4 files changed, 29 insertions(+), 3 deletions(-)
--
2.17.1
[ 2.919522] test_bpf: #0 TAX jited:1 987 194 193 PASS
[ 2.923207] test_bpf: #1 TXA jited:1 263 176 127 PASS
[ 2.927592] test_bpf: #2 ADD_SUB_MUL_K jited:1 135 PASS
[ 2.930068] test_bpf: #3 DIV_MOD_KX jited:1 205 PASS
[ 2.931805] test_bpf: #4 AND_OR_LSH_K jited:1 141 460 PASS
[ 2.933425] test_bpf: #5 LD_IMM_0 jited:1 153 PASS
[ 2.934838] test_bpf: #6 LD_IND jited:1 517 308 702 PASS
[ 2.937485] test_bpf: #7 LD_ABS jited:1 797 532 310 PASS
[ 2.941277] test_bpf: #8 LD_ABS_LL jited:1 731 497 PASS
[ 2.944710] test_bpf: #9 LD_IND_LL jited:1 370 286 284 PASS
[ 2.947049] test_bpf: #10 LD_ABS_NET jited:1 612 736 PASS
[ 2.949609] test_bpf: #11 LD_IND_NET jited:1 385 282 292 PASS
[ 2.951948] test_bpf: #12 LD_PKTTYPE jited:1 175 100 PASS
[ 2.953870] test_bpf: #13 LD_MARK jited:1 146 95 PASS
[ 2.955548] test_bpf: #14 LD_RXHASH jited:1 414 114 PASS
[ 2.957622] test_bpf: #15 LD_QUEUE jited:1 165 96 PASS
[ 2.959847] test_bpf: #16 LD_PROTOCOL jited:1 226 119 PASS
[ 2.962159] test_bpf: #17 LD_VLAN_TAG jited:1 141 94 PASS
[ 2.963804] test_bpf: #18 LD_VLAN_TAG_PRESENT jited:1 143 94 PASS
[ 2.965731] test_bpf: #19 LD_IFINDEX jited:1 149 95 PASS
[ 2.967343] test_bpf: #20 LD_HATYPE jited:1 160 95 PASS
[ 2.969453] test_bpf: #21 LD_CPU jited:1 779 406 PASS
[ 2.973687] test_bpf: #22 LD_NLATTR jited:1 275 385 PASS
[ 2.975843] test_bpf: #23 LD_NLATTR_NEST jited:1 1114 1831 PASS
[ 2.980776] test_bpf: #24 LD_PAYLOAD_OFF jited:1 3821 6196 PASS
[ 2.993068] test_bpf: #25 LD_ANC_XOR jited:1 138 89 PASS
[ 2.994591] test_bpf: #26 SPILL_FILL jited:1 162 104 104 PASS
[ 2.996727] test_bpf: #27 JEQ jited:1 417 135 129 PASS
[ 2.998774] test_bpf: #28 JGT jited:1 701 226 227 PASS
[ 3.002042] test_bpf: #29 JGE (jt 0), test 1 jited:1 680 134 108 PASS
[ 3.005355] test_bpf: #30 JGE (jt 0), test 2 jited:1 218 108 128 PASS
[ 3.007374] test_bpf: #31 JGE jited:1 363 292 226 PASS
[ 3.010347] test_bpf: #32 JSET jited:1 304 215 256 PASS
[ 3.013077] test_bpf: #33 tcpdump port 22 jited:1 472 518 487 PASS
[ 3.016133] test_bpf: #34 tcpdump complex jited:1 405 473 629 PASS
[ 3.019679] test_bpf: #35 RET_A jited:1 145 324 PASS
[ 3.021296] test_bpf: #36 INT: ADD trivial jited:1 133 PASS
[ 3.022619] test_bpf: #37 INT: MUL_X jited:1 139 PASS
[ 3.023853] test_bpf: #38 INT: MUL_X2 jited:1 361 PASS
[ 3.025355] test_bpf: #39 INT: MUL32_X jited:1 158 PASS
[ 3.026556] test_bpf: #40 INT: ADD 64-bit jited:1 311 PASS
[ 3.028192] test_bpf: #41 INT: ADD 32-bit jited:1 332 PASS
[ 3.030368] test_bpf: #42 INT: SUB jited:1 426 PASS
[ 3.034420] test_bpf: #43 INT: XOR jited:1 257 PASS
[ 3.035985] test_bpf: #44 INT: MUL jited:1 195 PASS
[ 3.037582] test_bpf: #45 MOV REG64 jited:1 143 PASS
[ 3.038930] test_bpf: #46 MOV REG32 jited:1 149 PASS
[ 3.040342] test_bpf: #47 LD IMM64 jited:1 162 PASS
[ 3.042740] test_bpf: #48 INT: ALU MIX jited:1 191 PASS
[ 3.044145] test_bpf: #49 INT: shifts by register jited:1 217 PASS
[ 3.045767] test_bpf: #50 check: missing ret PASS
[ 3.046306] test_bpf: #51 check: div_k_0 PASS
[ 3.046679] test_bpf: #52 check: unknown insn PASS
[ 3.047067] test_bpf: #53 check: out of range spill/fill PASS
[ 3.047488] test_bpf: #54 JUMPS + HOLES jited:1 283 PASS
[ 3.050824] test_bpf: #55 check: RET X PASS
[ 3.051267] test_bpf: #56 check: LDX + RET X PASS
[ 3.051732] test_bpf: #57 M[]: alt STX + LDX jited:1 544 PASS
[ 3.053593] test_bpf: #58 M[]: full STX + full LDX jited:1 265 PASS
[ 3.055167] test_bpf: #59 check: SKF_AD_MAX PASS
[ 3.055695] test_bpf: #60 LD [SKF_AD_OFF-1] jited:1 611 PASS
[ 3.057511] test_bpf: #61 load 64-bit immediate jited:1 157 PASS
[ 3.058997] test_bpf: #62 ALU_MOV_X: dst = 2 jited:1 135 PASS
[ 3.060344] test_bpf: #63 ALU_MOV_X: dst = 4294967295 jited:1 289 PASS
[ 3.063116] test_bpf: #64 ALU64_MOV_X: dst = 2 jited:1 859 PASS
[ 3.066072] test_bpf: #65 ALU64_MOV_X: dst = 4294967295 jited:1 145 PASS
[ 3.067488] test_bpf: #66 ALU_MOV_K: dst = 2 jited:1 165 PASS
[ 3.069167] test_bpf: #67 ALU_MOV_K: dst = 4294967295 jited:1 140 PASS
[ 3.070503] test_bpf: #68 ALU_MOV_K: 0x0000ffffffff0000 = 0x00000000ffffffff jited:1 151 PASS
[ 3.072297] test_bpf: #69 ALU64_MOV_K: dst = 2 jited:1 144 PASS
[ 3.074009] test_bpf: #70 ALU64_MOV_K: dst = 2147483647 jited:1 168 PASS
[ 3.076184] test_bpf: #71 ALU64_OR_K: dst = 0x0 jited:1 159 PASS
[ 3.077754] test_bpf: #72 ALU64_MOV_K: dst = -1 jited:1 157 PASS
[ 3.078945] test_bpf: #73 ALU_ADD_X: 1 + 2 = 3 jited:1 139 PASS
[ 3.080084] test_bpf: #74 ALU_ADD_X: 1 + 4294967294 = 4294967295 jited:1 146 PASS
[ 3.081600] test_bpf: #75 ALU_ADD_X: 2 + 4294967294 = 0 jited:1 155 PASS
[ 3.082878] test_bpf: #76 ALU64_ADD_X: 1 + 2 = 3 jited:1 132 PASS
[ 3.084093] test_bpf: #77 ALU64_ADD_X: 1 + 4294967294 = 4294967295 jited:1 151 PASS
[ 3.085632] test_bpf: #78 ALU64_ADD_X: 2 + 4294967294 = 4294967296 jited:1 158 PASS
[ 3.087125] test_bpf: #79 ALU_ADD_K: 1 + 2 = 3 jited:1 143 PASS
[ 3.088282] test_bpf: #80 ALU_ADD_K: 3 + 0 = 3 jited:1 136 PASS
[ 3.089800] test_bpf: #81 ALU_ADD_K: 1 + 4294967294 = 4294967295 jited:1 135 PASS
[ 3.091023] test_bpf: #82 ALU_ADD_K: 4294967294 + 2 = 0 jited:1 162 PASS
[ 3.093223] test_bpf: #83 ALU_ADD_K: 0 + (-1) = 0x00000000ffffffff jited:1 219 PASS
[ 3.095641] test_bpf: #84 ALU_ADD_K: 0 + 0xffff = 0xffff jited:1 396 PASS
[ 3.097484] test_bpf: #85 ALU_ADD_K: 0 + 0x7fffffff = 0x7fffffff jited:1 141 PASS
[ 3.098834] test_bpf: #86 ALU_ADD_K: 0 + 0x80000000 = 0x80000000 jited:1 150 PASS
[ 3.100319] test_bpf: #87 ALU_ADD_K: 0 + 0x80008000 = 0x80008000 jited:1 147 PASS
[ 3.101792] test_bpf: #88 ALU64_ADD_K: 1 + 2 = 3 jited:1 143 PASS
[ 3.103016] test_bpf: #89 ALU64_ADD_K: 3 + 0 = 3 jited:1 132 PASS
[ 3.104256] test_bpf: #90 ALU64_ADD_K: 1 + 2147483646 = 2147483647 jited:1 150 PASS
[ 3.105975] test_bpf: #91 ALU64_ADD_K: 4294967294 + 2 = 4294967296 jited:1 159 PASS
[ 3.107398] test_bpf: #92 ALU64_ADD_K: 2147483646 + -2147483647 = -1 jited:1 156 PASS
[ 3.109531] test_bpf: #93 ALU64_ADD_K: 1 + 0 = 1 jited:1 159 PASS
[ 3.111031] test_bpf: #94 ALU64_ADD_K: 0 + (-1) = 0xffffffffffffffff jited:1 170 PASS
[ 3.112616] test_bpf: #95 ALU64_ADD_K: 0 + 0xffff = 0xffff jited:1 152 PASS
[ 3.114216] test_bpf: #96 ALU64_ADD_K: 0 + 0x7fffffff = 0x7fffffff jited:1 157 PASS
[ 3.115635] test_bpf: #97 ALU64_ADD_K: 0 + 0x80000000 = 0xffffffff80000000 jited:1 145 PASS
[ 3.117354] test_bpf: #98 ALU_ADD_K: 0 + 0x80008000 = 0xffffffff80008000 jited:1 155 PASS
[ 3.118834] test_bpf: #99 ALU_SUB_X: 3 - 1 = 2 jited:1 143 PASS
[ 3.120210] test_bpf: #100 ALU_SUB_X: 4294967295 - 4294967294 = 1 jited:1 138 PASS
[ 3.121921] test_bpf: #101 ALU64_SUB_X: 3 - 1 = 2 jited:1 150 PASS
[ 3.123551] test_bpf: #102 ALU64_SUB_X: 4294967295 - 4294967294 = 1 jited:1 447 PASS
[ 3.126613] test_bpf: #103 ALU_SUB_K: 3 - 1 = 2 jited:1 150 PASS
[ 3.128422] test_bpf: #104 ALU_SUB_K: 3 - 0 = 3 jited:1 148 PASS
[ 3.130110] test_bpf: #105 ALU_SUB_K: 4294967295 - 4294967294 = 1 jited:1 129 PASS
[ 3.131444] test_bpf: #106 ALU64_SUB_K: 3 - 1 = 2 jited:1 132 PASS
[ 3.132943] test_bpf: #107 ALU64_SUB_K: 3 - 0 = 3 jited:1 146 PASS
[ 3.134318] test_bpf: #108 ALU64_SUB_K: 4294967294 - 4294967295 = -1 jited:1 137 PASS
[ 3.135551] test_bpf: #109 ALU64_ADD_K: 2147483646 - 2147483647 = -1 jited:1 135 PASS
[ 3.137209] test_bpf: #110 ALU_MUL_X: 2 * 3 = 6 jited:1 149 PASS
[ 3.138467] test_bpf: #111 ALU_MUL_X: 2 * 0x7FFFFFF8 = 0xFFFFFFF0 jited:1 148 PASS
[ 3.139855] test_bpf: #112 ALU_MUL_X: -1 * -1 = 1 jited:1 411 PASS
[ 3.141812] test_bpf: #113 ALU64_MUL_X: 2 * 3 = 6 jited:1 156 PASS
[ 3.143409] test_bpf: #114 ALU64_MUL_X: 1 * 2147483647 = 2147483647 jited:1 161 PASS
[ 3.145054] test_bpf: #115 ALU_MUL_K: 2 * 3 = 6 jited:1 138 PASS
[ 3.146306] test_bpf: #116 ALU_MUL_K: 3 * 1 = 3 jited:1 136 PASS
[ 3.147553] test_bpf: #117 ALU_MUL_K: 2 * 0x7FFFFFF8 = 0xFFFFFFF0 jited:1 132 PASS
[ 3.149023] test_bpf: #118 ALU_MUL_K: 1 * (-1) = 0x00000000ffffffff jited:1 143 PASS
[ 3.150528] test_bpf: #119 ALU64_MUL_K: 2 * 3 = 6 jited:1 143 PASS
[ 3.151771] test_bpf: #120 ALU64_MUL_K: 3 * 1 = 3 jited:1 139 PASS
[ 3.153208] test_bpf: #121 ALU64_MUL_K: 1 * 2147483647 = 2147483647 jited:1 167 PASS
[ 3.154950] test_bpf: #122 ALU64_MUL_K: 1 * -2147483647 = -2147483647 jited:1 137 PASS
[ 3.157836] test_bpf: #123 ALU64_MUL_K: 1 * (-1) = 0xffffffffffffffff jited:1 164 PASS
[ 3.159724] test_bpf: #124 ALU_DIV_X: 6 / 2 = 3 jited:1 137 PASS
[ 3.161149] test_bpf: #125 ALU_DIV_X: 4294967295 / 4294967295 = 1 jited:1 155 PASS
[ 3.162424] test_bpf: #126 ALU64_DIV_X: 6 / 2 = 3 jited:1 148 PASS
[ 3.163586] test_bpf: #127 ALU64_DIV_X: 2147483647 / 2147483647 = 1 jited:1 153 PASS
[ 3.165093] test_bpf: #128 ALU64_DIV_X: 0xffffffffffffffff / (-1) = 0x0000000000000001 jited:1 166 PASS
[ 3.166563] test_bpf: #129 ALU_DIV_K: 6 / 2 = 3 jited:1 152 PASS
[ 3.167861] test_bpf: #130 ALU_DIV_K: 3 / 1 = 3 jited:1 147 PASS
[ 3.169241] test_bpf: #131 ALU_DIV_K: 4294967295 / 4294967295 = 1 jited:1 146 PASS
[ 3.170672] test_bpf: #132 ALU_DIV_K: 0xffffffffffffffff / (-1) = 0x1 jited:1 282 PASS
[ 3.173072] test_bpf: #133 ALU64_DIV_K: 6 / 2 = 3 jited:1 260 PASS
[ 3.175428] test_bpf: #134 ALU64_DIV_K: 3 / 1 = 3 jited:1 194 PASS
[ 3.177417] test_bpf: #135 ALU64_DIV_K: 2147483647 / 2147483647 = 1 jited:1 156 PASS
[ 3.178942] test_bpf: #136 ALU64_DIV_K: 0xffffffffffffffff / (-1) = 0x0000000000000001 jited:1 178 PASS
[ 3.180620] test_bpf: #137 ALU_MOD_X: 3 % 2 = 1 jited:1 156 PASS
[ 3.181939] test_bpf: #138 ALU_MOD_X: 4294967295 % 4294967293 = 2 jited:1 158 PASS
[ 3.183370] test_bpf: #139 ALU64_MOD_X: 3 % 2 = 1 jited:1 150 PASS
[ 3.185054] test_bpf: #140 ALU64_MOD_X: 2147483647 % 2147483645 = 2 jited:1 183 PASS
[ 3.187168] test_bpf: #141 ALU_MOD_K: 3 % 2 = 1 jited:1 183 PASS
[ 3.190961] test_bpf: #142 ALU_MOD_K: 3 % 1 = 0 jited:1 PASS
[ 3.192079] test_bpf: #143 ALU_MOD_K: 4294967295 % 4294967293 = 2 jited:1 163 PASS
[ 3.193673] test_bpf: #144 ALU64_MOD_K: 3 % 2 = 1 jited:1 156 PASS
[ 3.195055] test_bpf: #145 ALU64_MOD_K: 3 % 1 = 0 jited:1 PASS
[ 3.196025] test_bpf: #146 ALU64_MOD_K: 2147483647 % 2147483645 = 2 jited:1 352 PASS
[ 3.197453] test_bpf: #147 ALU_AND_X: 3 & 2 = 2 jited:1 142 PASS
[ 3.198692] test_bpf: #148 ALU_AND_X: 0xffffffff & 0xffffffff = 0xffffffff jited:1 135 PASS
[ 3.199963] test_bpf: #149 ALU64_AND_X: 3 & 2 = 2 jited:1 144 PASS
[ 3.201507] test_bpf: #150 ALU64_AND_X: 0xffffffff & 0xffffffff = 0xffffffff jited:1 137 PASS
[ 3.202894] test_bpf: #151 ALU_AND_K: 3 & 2 = 2 jited:1 141 PASS
[ 3.204160] test_bpf: #152 ALU_AND_K: 0xffffffff & 0xffffffff = 0xffffffff jited:1 148 PASS
[ 3.205941] test_bpf: #153 ALU64_AND_K: 3 & 2 = 2 jited:1 201 PASS
[ 3.207826] test_bpf: #154 ALU64_AND_K: 0xffffffff & 0xffffffff = 0xffffffff jited:1 355 PASS
[ 3.209478] test_bpf: #155 ALU64_AND_K: 0x0000ffffffff0000 & 0x0 = 0x0000ffff00000000 jited:1 161 PASS
[ 3.211018] test_bpf: #156 ALU64_AND_K: 0x0000ffffffff0000 & -1 = 0x0000ffffffffffff jited:1 150 PASS
[ 3.212661] test_bpf: #157 ALU64_AND_K: 0xffffffffffffffff & -1 = 0xffffffffffffffff jited:1 156 PASS
[ 3.214231] test_bpf: #158 ALU_OR_X: 1 | 2 = 3 jited:1 134 PASS
[ 3.215457] test_bpf: #159 ALU_OR_X: 0x0 | 0xffffffff = 0xffffffff jited:1 195 PASS
[ 3.217672] test_bpf: #160 ALU64_OR_X: 1 | 2 = 3 jited:1 364 PASS
[ 3.221535] test_bpf: #161 ALU64_OR_X: 0 | 0xffffffff = 0xffffffff jited:1 294 PASS
[ 3.224273] test_bpf: #162 ALU_OR_K: 1 | 2 = 3 jited:1 150 PASS
[ 3.226569] test_bpf: #163 ALU_OR_K: 0 & 0xffffffff = 0xffffffff jited:1 132 PASS
[ 3.228142] test_bpf: #164 ALU64_OR_K: 1 | 2 = 3 jited:1 145 PASS
[ 3.229782] test_bpf: #165 ALU64_OR_K: 0 & 0xffffffff = 0xffffffff jited:1 135 PASS
[ 3.231020] test_bpf: #166 ALU64_OR_K: 0x0000ffffffff0000 | 0x0 = 0x0000ffff00000000 jited:1 156 PASS
[ 3.232640] test_bpf: #167 ALU64_OR_K: 0x0000ffffffff0000 | -1 = 0xffffffffffffffff jited:1 10199 PASS
[ 3.244116] test_bpf: #168 ALU64_OR_K: 0x000000000000000 | -1 = 0xffffffffffffffff jited:1 156 PASS
[ 3.245865] test_bpf: #169 ALU_XOR_X: 5 ^ 6 = 3 jited:1 143 PASS
[ 3.247137] test_bpf: #170 ALU_XOR_X: 0x1 ^ 0xffffffff = 0xfffffffe jited:1 142 PASS
[ 3.248739] test_bpf: #171 ALU64_XOR_X: 5 ^ 6 = 3 jited:1 274 PASS
[ 3.251117] test_bpf: #172 ALU64_XOR_X: 1 ^ 0xffffffff = 0xfffffffe jited:1 170 PASS
[ 3.253139] test_bpf: #173 ALU_XOR_K: 5 ^ 6 = 3 jited:1 145 PASS
[ 3.254406] test_bpf: #174 ALU_XOR_K: 1 ^ 0xffffffff = 0xfffffffe jited:1 131 PASS
[ 3.256068] test_bpf: #175 ALU64_XOR_K: 5 ^ 6 = 3 jited:1 183 PASS
[ 3.258485] test_bpf: #176 ALU64_XOR_K: 1 & 0xffffffff = 0xfffffffe jited:1 144 PASS
[ 3.259866] test_bpf: #177 ALU64_XOR_K: 0x0000ffffffff0000 ^ 0x0 = 0x0000ffffffff0000 jited:1 401 PASS
[ 3.261465] test_bpf: #178 ALU64_XOR_K: 0x0000ffffffff0000 ^ -1 = 0xffff00000000ffff jited:1 154 PASS
[ 3.262836] test_bpf: #179 ALU64_XOR_K: 0x000000000000000 ^ -1 = 0xffffffffffffffff jited:1 154 PASS
[ 3.264244] test_bpf: #180 ALU_LSH_X: 1 << 1 = 2 jited:1 139 PASS
[ 3.265675] test_bpf: #181 ALU_LSH_X: 1 << 31 = 0x80000000 jited:1 143 PASS
[ 3.266977] test_bpf: #182 ALU64_LSH_X: 1 << 1 = 2 jited:1 135 PASS
[ 3.268213] test_bpf: #183 ALU64_LSH_X: 1 << 31 = 0x80000000 jited:1 148 PASS
[ 3.269886] test_bpf: #184 ALU_LSH_K: 1 << 1 = 2 jited:1 138 PASS
[ 3.271070] test_bpf: #185 ALU_LSH_K: 1 << 31 = 0x80000000 jited:1 142 PASS
[ 3.272248] test_bpf: #186 ALU64_LSH_K: 1 << 1 = 2 jited:1 136 PASS
[ 3.273787] test_bpf: #187 ALU64_LSH_K: 1 << 31 = 0x80000000 jited:1 142 PASS
[ 3.275048] test_bpf: #188 ALU_RSH_X: 2 >> 1 = 1 jited:1 135 PASS
[ 3.276239] test_bpf: #189 ALU_RSH_X: 0x80000000 >> 31 = 1 jited:1 145 PASS
[ 3.277814] test_bpf: #190 ALU64_RSH_X: 2 >> 1 = 1 jited:1 211 PASS
[ 3.279397] test_bpf: #191 ALU64_RSH_X: 0x80000000 >> 31 = 1 jited:1 426 PASS
[ 3.283103] test_bpf: #192 ALU_RSH_K: 2 >> 1 = 1 jited:1 143 PASS
[ 3.284957] test_bpf: #193 ALU_RSH_K: 0x80000000 >> 31 = 1 jited:1 140 PASS
[ 3.286449] test_bpf: #194 ALU64_RSH_K: 2 >> 1 = 1 jited:1 139 PASS
[ 3.287772] test_bpf: #195 ALU64_RSH_K: 0x80000000 >> 31 = 1 jited:1 133 PASS
[ 3.289334] test_bpf: #196 ALU_ARSH_X: 0xff00ff0000000000 >> 40 = 0xffffffffffff00ff jited:1 274 PASS
[ 3.291630] test_bpf: #197 ALU_ARSH_K: 0xff00ff0000000000 >> 40 = 0xffffffffffff00ff jited:1 188 PASS
[ 3.294335] test_bpf: #198 ALU_NEG: -(3) = -3 jited:1 211 PASS
[ 3.295948] test_bpf: #199 ALU_NEG: -(-3) = 3 jited:1 155 PASS
[ 3.297481] test_bpf: #200 ALU64_NEG: -(3) = -3 jited:1 142 PASS
[ 3.298701] test_bpf: #201 ALU64_NEG: -(-3) = 3 jited:1 137 PASS
[ 3.299912] test_bpf: #202 ALU_END_FROM_BE 16: 0x0123456789abcdef -> 0xcdef jited:1 347 PASS
[ 3.301435] test_bpf: #203 ALU_END_FROM_BE 32: 0x0123456789abcdef -> 0x89abcdef jited:1 146 PASS
[ 3.302934] test_bpf: #204 ALU_END_FROM_BE 64: 0x0123456789abcdef -> 0x89abcdef jited:1 138 PASS
[ 3.304700] test_bpf: #205 ALU_END_FROM_LE 16: 0x0123456789abcdef -> 0xefcd jited:1 167 PASS
[ 3.306339] test_bpf: #206 ALU_END_FROM_LE 32: 0x0123456789abcdef -> 0xefcdab89 jited:1 141 PASS
[ 3.307769] test_bpf: #207 ALU_END_FROM_LE 64: 0x0123456789abcdef -> 0x67452301 jited:1 144 PASS
[ 3.309689] test_bpf: #208 ST_MEM_B: Store/Load byte: max negative jited:1 236 PASS
[ 3.311928] test_bpf: #209 ST_MEM_B: Store/Load byte: max positive jited:1 291 PASS
[ 3.315177] test_bpf: #210 STX_MEM_B: Store/Load byte: max negative jited:1 145 PASS
[ 3.316975] test_bpf: #211 ST_MEM_H: Store/Load half word: max negative jited:1 157 PASS
[ 3.318401] test_bpf: #212 ST_MEM_H: Store/Load half word: max positive jited:1 150 PASS
[ 3.319755] test_bpf: #213 STX_MEM_H: Store/Load half word: max negative jited:1 345 PASS
[ 3.321456] test_bpf: #214 ST_MEM_W: Store/Load word: max negative jited:1 240 PASS
[ 3.323595] test_bpf: #215 ST_MEM_W: Store/Load word: max positive jited:1 614 PASS
[ 3.326144] test_bpf: #216 STX_MEM_W: Store/Load word: max negative jited:1 193 PASS
[ 3.328180] test_bpf: #217 ST_MEM_DW: Store/Load double word: max negative jited:1 150 PASS
[ 3.330030] test_bpf: #218 ST_MEM_DW: Store/Load double word: max negative 2 jited:1 170 PASS
[ 3.331586] test_bpf: #219 ST_MEM_DW: Store/Load double word: max positive jited:1 150 PASS
[ 3.333343] test_bpf: #220 STX_MEM_DW: Store/Load double word: max negative jited:1 149 PASS
[ 3.334785] test_bpf: #221 STX_XADD_W: Test: 0x12 + 0x10 = 0x22 jited:1 183 PASS
[ 3.337023] test_bpf: #222 STX_XADD_W: Test side-effects, r10: 0x12 + 0x10 = 0x22 jited:1 PASS
[ 3.338288] test_bpf: #223 STX_XADD_W: Test side-effects, r0: 0x12 + 0x10 = 0x22 jited:1 190 PASS
[ 3.339819] test_bpf: #224 STX_XADD_W: X + 1 + 1 + 1 + ... jited:1 293940 PASS
[ 3.677406] test_bpf: #225 STX_XADD_DW: Test: 0x12 + 0x10 = 0x22 jited:1 196 PASS
[ 3.678965] test_bpf: #226 STX_XADD_DW: Test side-effects, r10: 0x12 + 0x10 = 0x22 jited:1 PASS
[ 3.680420] test_bpf: #227 STX_XADD_DW: Test side-effects, r0: 0x12 + 0x10 = 0x22 jited:1 200 PASS
[ 3.682185] test_bpf: #228 STX_XADD_DW: X + 1 + 1 + 1 + ... jited:1 272599 PASS
[ 4.014412] test_bpf: #229 JMP_EXIT jited:1 149 PASS
[ 4.015722] test_bpf: #230 JMP_JA: Unconditional jump: if (true) return 1 jited:1 150 PASS
[ 4.017263] test_bpf: #231 JMP_JSLT_K: Signed jump: if (-2 < -1) return 1 jited:1 160 PASS
[ 4.018644] test_bpf: #232 JMP_JSLT_K: Signed jump: if (-1 < -1) return 0 jited:1 148 PASS
[ 4.020070] test_bpf: #233 JMP_JSGT_K: Signed jump: if (-1 > -2) return 1 jited:1 150 PASS
[ 4.021766] test_bpf: #234 JMP_JSGT_K: Signed jump: if (-1 > -1) return 0 jited:1 155 PASS
[ 4.023142] test_bpf: #235 JMP_JSLE_K: Signed jump: if (-2 <= -1) return 1 jited:1 147 PASS
[ 4.024704] test_bpf: #236 JMP_JSLE_K: Signed jump: if (-1 <= -1) return 1 jited:1 274 PASS
[ 4.027332] test_bpf: #237 JMP_JSLE_K: Signed jump: value walk 1 jited:1 320 PASS
[ 4.031351] test_bpf: #238 JMP_JSLE_K: Signed jump: value walk 2 jited:1 673 PASS
[ 4.034132] test_bpf: #239 JMP_JSGE_K: Signed jump: if (-1 >= -2) return 1 jited:1 166 PASS
[ 4.035964] test_bpf: #240 JMP_JSGE_K: Signed jump: if (-1 >= -1) return 1 jited:1 196 PASS
[ 4.038053] test_bpf: #241 JMP_JSGE_K: Signed jump: value walk 1 jited:1 186 PASS
[ 4.039617] test_bpf: #242 JMP_JSGE_K: Signed jump: value walk 2 jited:1 288 PASS
[ 4.042982] test_bpf: #243 JMP_JGT_K: if (3 > 2) return 1 jited:1 548 PASS
[ 4.045646] test_bpf: #244 JMP_JGT_K: Unsigned jump: if (-1 > 1) return 1 jited:1 155 PASS
[ 4.047319] test_bpf: #245 JMP_JLT_K: if (2 < 3) return 1 jited:1 145 PASS
[ 4.049036] test_bpf: #246 JMP_JGT_K: Unsigned jump: if (1 < -1) return 1 jited:1 156 PASS
[ 4.050573] test_bpf: #247 JMP_JGE_K: if (3 >= 2) return 1 jited:1 146 PASS
[ 4.051832] test_bpf: #248 JMP_JLE_K: if (2 <= 3) return 1 jited:1 352 PASS
[ 4.053407] test_bpf: #249 JMP_JGT_K: if (3 > 2) return 1 (jump backwards) jited:1 216 PASS
[ 4.055014] test_bpf: #250 JMP_JGE_K: if (3 >= 3) return 1 jited:1 153 PASS
[ 4.056603] test_bpf: #251 JMP_JGT_K: if (2 < 3) return 1 (jump backwards) jited:1 289 PASS
[ 4.058880] test_bpf: #252 JMP_JLE_K: if (3 <= 3) return 1 jited:1 271 PASS
[ 4.061612] test_bpf: #253 JMP_JNE_K: if (3 != 2) return 1 jited:1 212 PASS
[ 4.063329] test_bpf: #254 JMP_JEQ_K: if (3 == 3) return 1 jited:1 162 PASS
[ 4.064919] test_bpf: #255 JMP_JSET_K: if (0x3 & 0x2) return 1 jited:1 150 PASS
[ 4.066530] test_bpf: #256 JMP_JSET_K: if (0x3 & 0xffffffff) return 1 jited:1 136 PASS
[ 4.068165] test_bpf: #257 JMP_JSGT_X: Signed jump: if (-1 > -2) return 1 jited:1 155 PASS
[ 4.069934] test_bpf: #258 JMP_JSGT_X: Signed jump: if (-1 > -1) return 0 jited:1 149 PASS
[ 4.071516] test_bpf: #259 JMP_JSLT_X: Signed jump: if (-2 < -1) return 1 jited:1 285 PASS
[ 4.075340] test_bpf: #260 JMP_JSLT_X: Signed jump: if (-1 < -1) return 0 jited:1 178 PASS
[ 4.077655] test_bpf: #261 JMP_JSGE_X: Signed jump: if (-1 >= -2) return 1 jited:1 146 PASS
[ 4.079337] test_bpf: #262 JMP_JSGE_X: Signed jump: if (-1 >= -1) return 1 jited:1 152 PASS
[ 4.081154] test_bpf: #263 JMP_JSLE_X: Signed jump: if (-2 <= -1) return 1 jited:1 152 PASS
[ 4.082646] test_bpf: #264 JMP_JSLE_X: Signed jump: if (-1 <= -1) return 1 jited:1 155 PASS
[ 4.084269] test_bpf: #265 JMP_JGT_X: if (3 > 2) return 1 jited:1 152 PASS
[ 4.086022] test_bpf: #266 JMP_JGT_X: Unsigned jump: if (-1 > 1) return 1 jited:1 157 PASS
[ 4.087673] test_bpf: #267 JMP_JLT_X: if (2 < 3) return 1 jited:1 372 PASS
[ 4.089431] test_bpf: #268 JMP_JLT_X: Unsigned jump: if (1 < -1) return 1 jited:1 149 PASS
[ 4.091012] test_bpf: #269 JMP_JGE_X: if (3 >= 2) return 1 jited:1 169 PASS
[ 4.093121] test_bpf: #270 JMP_JGE_X: if (3 >= 3) return 1 jited:1 172 PASS
[ 4.095324] test_bpf: #271 JMP_JLE_X: if (2 <= 3) return 1 jited:1 162 PASS
[ 4.097206] test_bpf: #272 JMP_JLE_X: if (3 <= 3) return 1 jited:1 162 PASS
[ 4.098809] test_bpf: #273 JMP_JGE_X: ldimm64 test 1 jited:1 151 PASS
[ 4.100653] test_bpf: #274 JMP_JGE_X: ldimm64 test 2 jited:1 156 PASS
[ 4.102400] test_bpf: #275 JMP_JGE_X: ldimm64 test 3 jited:1 298 PASS
[ 4.105455] test_bpf: #276 JMP_JLE_X: ldimm64 test 1 jited:1 305 PASS
[ 4.107974] test_bpf: #277 JMP_JLE_X: ldimm64 test 2 jited:1 305 PASS
[ 4.111003] test_bpf: #278 JMP_JLE_X: ldimm64 test 3 jited:1 167 PASS
[ 4.113004] test_bpf: #279 JMP_JNE_X: if (3 != 2) return 1 jited:1 157 PASS
[ 4.114525] test_bpf: #280 JMP_JEQ_X: if (3 == 3) return 1 jited:1 143 PASS
[ 4.116042] test_bpf: #281 JMP_JSET_X: if (0x3 & 0x2) return 1 jited:1 155 PASS
[ 4.117878] test_bpf: #282 JMP_JSET_X: if (0x3 & 0xffffffff) return 1 jited:1 144 PASS
[ 4.119426] test_bpf: #283 JMP_JA: Jump, gap, jump, ... jited:1 152 PASS
[ 4.121025] test_bpf: #284 BPF_MAXINSNS: Maximum possible literals jited:1 201 PASS
[ 4.166873] test_bpf: #285 BPF_MAXINSNS: Single literal jited:1 186 PASS
[ 4.188004] test_bpf: #286 BPF_MAXINSNS: Run/add until end jited:1 7654 PASS
[ 4.217607] test_bpf: #287 BPF_MAXINSNS: Too many instructions PASS
[ 4.217944] test_bpf: #288 BPF_MAXINSNS: Very long jump jited:1 185 PASS
[ 4.241039] test_bpf: #289 BPF_MAXINSNS: Ctx heavy transformations jited:1 25611 17838 PASS
[ 4.324277] test_bpf: #290 BPF_MAXINSNS: Call heavy transformations jited:1 1119508 1081236 PASS
[ 6.574203] test_bpf: #291 BPF_MAXINSNS: Jump heavy test jited:1 148700 PASS
[ 6.747041] test_bpf: #292 BPF_MAXINSNS: Very long jump backwards jited:1 256 PASS
[ 6.755815] test_bpf: #293 BPF_MAXINSNS: Edge hopping nuthouse jited:1 603199 PASS
[ 7.364405] test_bpf: #294 BPF_MAXINSNS: Jump, gap, jump, ... jited:1 508 PASS
[ 7.398180] test_bpf: #295 BPF_MAXINSNS: jump over MSH PASS
[ 7.494452] test_bpf: #296 BPF_MAXINSNS: exec all MSH jited:1 400957 PASS
[ 8.058424] test_bpf: #297 BPF_MAXINSNS: ld_abs+get_processor_id jited:1 526648 PASS
[ 8.665535] test_bpf: #298 LD_IND byte frag jited:1 711 PASS
[ 8.667800] test_bpf: #299 LD_IND halfword frag jited:1 858 PASS
[ 8.669971] test_bpf: #300 LD_IND word frag jited:1 632 PASS
[ 8.671870] test_bpf: #301 LD_IND halfword mixed head/frag jited:1 697 PASS
[ 8.674097] test_bpf: #302 LD_IND word mixed head/frag jited:1 641 PASS
[ 8.676013] test_bpf: #303 LD_ABS byte frag jited:1 979 PASS
[ 8.679099] test_bpf: #304 LD_ABS halfword frag jited:1 1404 PASS
[ 8.682879] test_bpf: #305 LD_ABS word frag jited:1 704 PASS
[ 8.685622] test_bpf: #306 LD_ABS halfword mixed head/frag jited:1 660 PASS
[ 8.687660] test_bpf: #307 LD_ABS word mixed head/frag jited:1 894 PASS
[ 8.689809] test_bpf: #308 LD_IND byte default X jited:1 277 PASS
[ 8.691308] test_bpf: #309 LD_IND byte positive offset jited:1 287 PASS
[ 8.693532] test_bpf: #310 LD_IND byte negative offset jited:1 521 PASS
[ 8.697795] test_bpf: #311 LD_IND byte positive offset, all ff jited:1 276 PASS
[ 8.699498] test_bpf: #312 LD_IND byte positive offset, out of bounds jited:1 719 PASS
[ 8.701690] test_bpf: #313 LD_IND byte negative offset, out of bounds jited:1 379 PASS
[ 8.703690] test_bpf: #314 LD_IND byte negative offset, multiple calls jited:1 1163 PASS
[ 8.706881] test_bpf: #315 LD_IND halfword positive offset jited:1 276 PASS
[ 8.708718] test_bpf: #316 LD_IND halfword negative offset jited:1 278 PASS
[ 8.710487] test_bpf: #317 LD_IND halfword unaligned jited:1 267 PASS
[ 8.712248] test_bpf: #318 LD_IND halfword positive offset, all ff jited:1 275 PASS
[ 8.713967] test_bpf: #319 LD_IND halfword positive offset, out of bounds jited:1 387 PASS
[ 8.715712] test_bpf: #320 LD_IND halfword negative offset, out of bounds jited:1 607 PASS
[ 8.717704] test_bpf: #321 LD_IND word positive offset jited:1 282 PASS
[ 8.719370] test_bpf: #322 LD_IND word negative offset jited:1 274 PASS
[ 8.721203] test_bpf: #323 LD_IND word unaligned (addr & 3 == 2) jited:1 272 PASS
[ 8.722933] test_bpf: #324 LD_IND word unaligned (addr & 3 == 1) jited:1 519 PASS
[ 8.725627] test_bpf: #325 LD_IND word unaligned (addr & 3 == 3) jited:1 303 PASS
[ 8.728111] test_bpf: #326 LD_IND word positive offset, all ff jited:1 284 PASS
[ 8.730019] test_bpf: #327 LD_IND word positive offset, out of bounds jited:1 386 PASS
[ 8.731784] test_bpf: #328 LD_IND word negative offset, out of bounds jited:1 647 PASS
[ 8.733707] test_bpf: #329 LD_ABS byte jited:1 181 PASS
[ 8.735196] test_bpf: #330 LD_ABS byte positive offset, all ff jited:1 186 PASS
[ 8.736838] test_bpf: #331 LD_ABS byte positive offset, out of bounds jited:1 480 PASS
[ 8.739205] test_bpf: #332 LD_ABS byte negative offset, out of bounds load PASS
[ 8.740065] test_bpf: #333 LD_ABS byte negative offset, in bounds jited:1 367 PASS
[ 8.742180] test_bpf: #334 LD_ABS byte negative offset, out of bounds jited:1 9394 PASS
[ 8.753233] test_bpf: #335 LD_ABS byte negative offset, multiple calls jited:1 1172 PASS
[ 8.757800] test_bpf: #336 LD_ABS halfword jited:1 174 PASS
[ 8.759928] test_bpf: #337 LD_ABS halfword unaligned jited:1 197 PASS
[ 8.761550] test_bpf: #338 LD_ABS halfword positive offset, all ff jited:1 180 PASS
[ 8.763154] test_bpf: #339 LD_ABS halfword positive offset, out of bounds jited:1 409 PASS
[ 8.765157] test_bpf: #340 LD_ABS halfword negative offset, out of bounds load PASS
[ 8.765793] test_bpf: #341 LD_ABS halfword negative offset, in bounds jited:1 381 PASS
[ 8.767438] test_bpf: #342 LD_ABS halfword negative offset, out of bounds jited:1 365 PASS
[ 8.769340] test_bpf: #343 LD_ABS word jited:1 174 PASS
[ 8.770802] test_bpf: #344 LD_ABS word unaligned (addr & 3 == 2) jited:1 191 PASS
[ 8.772678] test_bpf: #345 LD_ABS word unaligned (addr & 3 == 1) jited:1 222 PASS
[ 8.774679] test_bpf: #346 LD_ABS word unaligned (addr & 3 == 3) jited:1 236 PASS
[ 8.776594] test_bpf: #347 LD_ABS word positive offset, all ff jited:1 178 PASS
[ 8.778133] test_bpf: #348 LD_ABS word positive offset, out of bounds jited:1 409 PASS
[ 8.779981] test_bpf: #349 LD_ABS word negative offset, out of bounds load PASS
[ 8.780902] test_bpf: #350 LD_ABS word negative offset, in bounds jited:1 383 PASS
[ 8.782769] test_bpf: #351 LD_ABS word negative offset, out of bounds jited:1 390 PASS
[ 8.784979] test_bpf: #352 LDX_MSH standalone, preserved A jited:1 329 PASS
[ 8.789271] test_bpf: #353 LDX_MSH standalone, preserved A 2 jited:1 260 PASS
[ 8.791365] test_bpf: #354 LDX_MSH standalone, test result 1 jited:1 181 PASS
[ 8.793347] test_bpf: #355 LDX_MSH standalone, test result 2 jited:1 189 PASS
[ 8.794994] test_bpf: #356 LDX_MSH standalone, negative offset jited:1 363 PASS
[ 8.797072] test_bpf: #357 LDX_MSH standalone, negative offset 2 jited:1 372 PASS
[ 8.798997] test_bpf: #358 LDX_MSH standalone, out of bounds jited:1 406 PASS
[ 8.800970] test_bpf: #359 ADD default X jited:1 147 PASS
[ 8.802291] test_bpf: #360 ADD default A jited:1 139 PASS
[ 8.803555] test_bpf: #361 SUB default X jited:1 151 PASS
[ 8.805253] test_bpf: #362 SUB default A jited:1 149 PASS
[ 8.806625] test_bpf: #363 MUL default X jited:1 183 PASS
[ 8.808911] test_bpf: #364 MUL default A jited:1 138 PASS
[ 8.810182] test_bpf: #365 DIV default X jited:1 161 PASS
[ 8.811461] test_bpf: #366 DIV default A jited:1 148 PASS
[ 8.812921] test_bpf: #367 MOD default X jited:1 162 PASS
[ 8.814155] test_bpf: #368 MOD default A jited:1 155 PASS
[ 8.815415] test_bpf: #369 JMP EQ default A jited:1 163 PASS
[ 8.817342] test_bpf: #370 JMP EQ default X jited:1 296 PASS
[ 8.821026] test_bpf: #371 JNE signed compare, test 1 jited:1 163 PASS
[ 8.822509] test_bpf: #372 JNE signed compare, test 2 jited:1 275 PASS
[ 8.824604] test_bpf: #373 JNE signed compare, test 3 jited:1 154 PASS
[ 8.825964] test_bpf: #374 JNE signed compare, test 4 jited:1 144 PASS
[ 8.827221] test_bpf: #375 JNE signed compare, test 5 jited:1 153 PASS
[ 8.828876] test_bpf: #376 JNE signed compare, test 6 jited:1 147 PASS
[ 8.830166] test_bpf: #377 JNE signed compare, test 7 jited:1 167 PASS
[ 8.831512] test_bpf: Summary: 378 PASSED, 0 FAILED, [366/366 JIT'ed]
[ 8.833565] test_bpf: test_skb_segment: success in skb_segment!
^ permalink raw reply
* [PATCH v3 1/2] bpf: add __weak hook for allocating executable memory
From: Ard Biesheuvel @ 2018-11-23 9:41 UTC (permalink / raw)
To: linux-kernel
Cc: Ard Biesheuvel, Daniel Borkmann, Alexei Starovoitov,
Rick Edgecombe, Eric Dumazet, Jann Horn, Kees Cook, Jessica Yu,
Arnd Bergmann, Catalin Marinas, Will Deacon, Mark Rutland,
David S. Miller, linux-arm-kernel, netdev
In-Reply-To: <20181123094152.21368-1-ard.biesheuvel@linaro.org>
By default, BPF uses module_alloc() to allocate executable memory,
but this is not necessary on all arches and potentially undesirable
on some of them.
So break out the module_alloc() and module_memfree() calls into __weak
functions to allow them to be overridden in arch code.
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
kernel/bpf/core.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
index 1a796e0799ec..572dd74c26e3 100644
--- a/kernel/bpf/core.c
+++ b/kernel/bpf/core.c
@@ -609,6 +609,16 @@ static void bpf_jit_uncharge_modmem(u32 pages)
atomic_long_sub(pages, &bpf_jit_current);
}
+void *__weak bpf_jit_alloc_exec(unsigned long size)
+{
+ return module_alloc(size);
+}
+
+void __weak bpf_jit_free_exec(const void *addr)
+{
+ module_memfree(addr);
+}
+
struct bpf_binary_header *
bpf_jit_binary_alloc(unsigned int proglen, u8 **image_ptr,
unsigned int alignment,
@@ -626,7 +636,7 @@ bpf_jit_binary_alloc(unsigned int proglen, u8 **image_ptr,
if (bpf_jit_charge_modmem(pages))
return NULL;
- hdr = module_alloc(size);
+ hdr = bpf_jit_alloc_exec(size);
if (!hdr) {
bpf_jit_uncharge_modmem(pages);
return NULL;
@@ -650,7 +660,7 @@ void bpf_jit_binary_free(struct bpf_binary_header *hdr)
{
u32 pages = hdr->pages;
- module_memfree(hdr);
+ bpf_jit_free_exec(hdr);
bpf_jit_uncharge_modmem(pages);
}
--
2.17.1
^ permalink raw reply related
* [PATCH v3 2/2] arm64/bpf: don't allocate BPF JIT programs in module memory
From: Ard Biesheuvel @ 2018-11-23 9:41 UTC (permalink / raw)
To: linux-kernel
Cc: Ard Biesheuvel, Daniel Borkmann, Alexei Starovoitov,
Rick Edgecombe, Eric Dumazet, Jann Horn, Kees Cook, Jessica Yu,
Arnd Bergmann, Catalin Marinas, Will Deacon, Mark Rutland,
David S. Miller, linux-arm-kernel, netdev
In-Reply-To: <20181123094152.21368-1-ard.biesheuvel@linaro.org>
The arm64 module region is a 128 MB region that is kept close to
the core kernel, in order to ensure that relative branches are
always in range. So using the same region for programs that do
not have this restriction is wasteful, and preferably avoided.
Now that the core BPF JIT code permits the alloc/free routines to
be overridden, implement them by vmalloc()/vfree() calls from a
dedicated 128 MB region set aside for BPF programs. This ensures
that BPF programs are still in branching range of each other, which
is something the JIT currently depends upon (and is not guaranteed
when using module_alloc() on KASLR kernels like we do currently).
It also ensures that placement of BPF programs does not correlate
with the placement of the core kernel or modules, making it less
likely that leaking the former will reveal the latter.
This also solves an issue under KASAN, where shadow memory is
needlessly allocated for all BPF programs (which don't require KASAN
shadow pages since they are not KASAN instrumented)
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
arch/arm64/include/asm/memory.h | 3 +++
arch/arm64/include/asm/pgtable.h | 2 +-
arch/arm64/net/bpf_jit_comp.c | 13 +++++++++++++
3 files changed, 17 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
index b96442960aea..506e319da98f 100644
--- a/arch/arm64/include/asm/memory.h
+++ b/arch/arm64/include/asm/memory.h
@@ -69,6 +69,9 @@
#define PCI_IO_END (VMEMMAP_START - SZ_2M)
#define PCI_IO_START (PCI_IO_END - PCI_IO_SIZE)
#define FIXADDR_TOP (PCI_IO_START - SZ_2M)
+#define BPF_JIT_REGION_BASE (VMALLOC_END)
+#define BPF_JIT_REGION_SIZE (SZ_128M)
+#define BPF_JIT_REGION_END (BPF_JIT_REGION_BASE + BPF_JIT_REGION_SIZE)
#define KERNEL_START _text
#define KERNEL_END _end
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 50b1ef8584c0..9db98a4cd9b4 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -31,7 +31,7 @@
* and fixed mappings
*/
#define VMALLOC_START (MODULES_END)
-#define VMALLOC_END (PAGE_OFFSET - PUD_SIZE - VMEMMAP_SIZE - SZ_64K)
+#define VMALLOC_END (PAGE_OFFSET - PUD_SIZE - VMEMMAP_SIZE - BPF_JIT_REGION_SIZE - SZ_64K)
#define vmemmap ((struct page *)VMEMMAP_START - (memstart_addr >> PAGE_SHIFT))
diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c
index a6fdaea07c63..298beba29fa5 100644
--- a/arch/arm64/net/bpf_jit_comp.c
+++ b/arch/arm64/net/bpf_jit_comp.c
@@ -940,3 +940,16 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
tmp : orig_prog);
return prog;
}
+
+void *bpf_jit_alloc_exec(unsigned long size)
+{
+ return __vmalloc_node_range(size, PAGE_SIZE, BPF_JIT_REGION_BASE,
+ BPF_JIT_REGION_END, GFP_KERNEL,
+ PAGE_KERNEL_EXEC, 0, NUMA_NO_NODE,
+ __builtin_return_address(0));
+}
+
+void bpf_jit_free_exec(const void *addr)
+{
+ return vfree(addr);
+}
--
2.17.1
^ permalink raw reply related
* [PATCH] mm: Replace all open encodings for NUMA_NO_NODE
From: Anshuman Khandual @ 2018-11-23 9:54 UTC (permalink / raw)
To: linux-mm, linux-kernel
Cc: ocfs2-devel, linux-fbdev, dri-devel, netdev, intel-wired-lan,
linux-media, iommu, linux-rdma, dmaengine, linux-block,
sparclinux, linuxppc-dev, linux-ia64, linux-alpha, akpm,
jiangqi903, hverkuil
At present there are multiple places where invalid node number is encoded
as -1. Even though implicitly understood it is always better to have macros
in there. Replace these open encodings for an invalid node number with the
global macro NUMA_NO_NODE. This helps remove NUMA related assumptions like
'invalid node' from various places redirecting them to a common definition.
Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
---
Changes in V1:
- Dropped OCFS2 changes per Joseph
- Dropped media/video drivers changes per Hans
RFC - https://patchwork.kernel.org/patch/10678035/
Build tested this with multiple cross compiler options like alpha, sparc,
arm64, x86, powerpc, powerpc64le etc with their default config which might
not have compiled tested all driver related changes. I will appreciate
folks giving this a test in their respective build environment.
All these places for replacement were found by running the following grep
patterns on the entire kernel code. Please let me know if this might have
missed some instances. This might also have replaced some false positives.
I will appreciate suggestions, inputs and review.
1. git grep "nid == -1"
2. git grep "node == -1"
3. git grep "nid = -1"
4. git grep "node = -1"
arch/alpha/include/asm/topology.h | 2 +-
arch/ia64/kernel/numa.c | 2 +-
arch/ia64/mm/discontig.c | 6 +++---
arch/ia64/sn/kernel/io_common.c | 2 +-
arch/powerpc/include/asm/pci-bridge.h | 2 +-
arch/powerpc/kernel/paca.c | 2 +-
arch/powerpc/kernel/pci-common.c | 2 +-
arch/powerpc/mm/numa.c | 14 +++++++-------
arch/powerpc/platforms/powernv/memtrace.c | 4 ++--
arch/sparc/kernel/auxio_32.c | 2 +-
arch/sparc/kernel/pci_fire.c | 2 +-
arch/sparc/kernel/pci_schizo.c | 2 +-
arch/sparc/kernel/pcic.c | 6 +++---
arch/sparc/kernel/psycho_common.c | 2 +-
arch/sparc/kernel/sbus.c | 2 +-
arch/sparc/mm/init_64.c | 6 +++---
arch/sparc/prom/init_32.c | 2 +-
arch/sparc/prom/init_64.c | 4 ++--
arch/sparc/prom/tree_32.c | 12 ++++++------
arch/sparc/prom/tree_64.c | 18 +++++++++---------
arch/x86/include/asm/pci.h | 2 +-
arch/x86/kernel/apic/x2apic_uv_x.c | 6 +++---
arch/x86/kernel/smpboot.c | 2 +-
arch/x86/platform/olpc/olpc_dt.c | 16 ++++++++--------
drivers/block/mtip32xx/mtip32xx.c | 4 ++--
drivers/dma/dmaengine.c | 3 ++-
drivers/infiniband/hw/hfi1/affinity.c | 2 +-
drivers/infiniband/hw/hfi1/init.c | 2 +-
drivers/iommu/dmar.c | 4 ++--
drivers/iommu/intel-iommu.c | 2 +-
drivers/misc/sgi-xp/xpc_uv.c | 2 +-
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 4 ++--
init/init_task.c | 2 +-
kernel/kthread.c | 2 +-
kernel/sched/fair.c | 15 ++++++++-------
lib/cpumask.c | 2 +-
mm/huge_memory.c | 12 ++++++------
mm/hugetlb.c | 2 +-
mm/ksm.c | 2 +-
mm/memory.c | 6 +++---
mm/memory_hotplug.c | 12 ++++++------
mm/mempolicy.c | 2 +-
mm/page_alloc.c | 4 ++--
mm/page_ext.c | 2 +-
net/core/pktgen.c | 2 +-
net/qrtr/qrtr.c | 2 +-
tools/perf/bench/numa.c | 6 +++---
47 files changed, 109 insertions(+), 107 deletions(-)
diff --git a/arch/alpha/include/asm/topology.h b/arch/alpha/include/asm/topology.h
index e6e13a8..f6dc89c 100644
--- a/arch/alpha/include/asm/topology.h
+++ b/arch/alpha/include/asm/topology.h
@@ -29,7 +29,7 @@ static const struct cpumask *cpumask_of_node(int node)
{
int cpu;
- if (node == -1)
+ if (node == NUMA_NO_NODE)
return cpu_all_mask;
cpumask_clear(&node_to_cpumask_map[node]);
diff --git a/arch/ia64/kernel/numa.c b/arch/ia64/kernel/numa.c
index 92c3762..1315da6 100644
--- a/arch/ia64/kernel/numa.c
+++ b/arch/ia64/kernel/numa.c
@@ -74,7 +74,7 @@ void __init build_cpu_to_node_map(void)
cpumask_clear(&node_to_cpu_mask[node]);
for_each_possible_early_cpu(cpu) {
- node = -1;
+ node = NUMA_NO_NODE;
for (i = 0; i < NR_CPUS; ++i)
if (cpu_physical_id(cpu) == node_cpuid[i].phys_id) {
node = node_cpuid[i].nid;
diff --git a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c
index 8a96578..f9c3675 100644
--- a/arch/ia64/mm/discontig.c
+++ b/arch/ia64/mm/discontig.c
@@ -227,7 +227,7 @@ void __init setup_per_cpu_areas(void)
* CPUs are put into groups according to node. Walk cpu_map
* and create new groups at node boundaries.
*/
- prev_node = -1;
+ prev_node = NUMA_NO_NODE;
ai->nr_groups = 0;
for (unit = 0; unit < nr_units; unit++) {
cpu = cpu_map[unit];
@@ -435,7 +435,7 @@ static void __init *memory_less_node_alloc(int nid, unsigned long pernodesize)
{
void *ptr = NULL;
u8 best = 0xff;
- int bestnode = -1, node, anynode = 0;
+ int bestnode = NUMA_NO_NODE, node, anynode = 0;
for_each_online_node(node) {
if (node_isset(node, memory_less_mask))
@@ -447,7 +447,7 @@ static void __init *memory_less_node_alloc(int nid, unsigned long pernodesize)
anynode = node;
}
- if (bestnode == -1)
+ if (bestnode == NUMA_NO_NODE)
bestnode = anynode;
ptr = memblock_alloc_try_nid(pernodesize, PERCPU_PAGE_SIZE,
diff --git a/arch/ia64/sn/kernel/io_common.c b/arch/ia64/sn/kernel/io_common.c
index 8df13d0..86b3fcb 100644
--- a/arch/ia64/sn/kernel/io_common.c
+++ b/arch/ia64/sn/kernel/io_common.c
@@ -344,7 +344,7 @@ sn_common_bus_fixup(struct pci_bus *bus,
printk(KERN_WARNING "on node %d but only %d nodes online."
"Association set to undetermined.\n",
controller->node, num_online_nodes());
- controller->node = -1;
+ controller->node = NUMA_NO_NODE;
}
}
diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h
index 94d4490..25a9e33 100644
--- a/arch/powerpc/include/asm/pci-bridge.h
+++ b/arch/powerpc/include/asm/pci-bridge.h
@@ -264,7 +264,7 @@ extern int pcibios_map_io_space(struct pci_bus *bus);
#ifdef CONFIG_NUMA
#define PHB_SET_NODE(PHB, NODE) ((PHB)->node = (NODE))
#else
-#define PHB_SET_NODE(PHB, NODE) ((PHB)->node = -1)
+#define PHB_SET_NODE(PHB, NODE) ((PHB)->node = NUMA_NO_NODE)
#endif
#endif /* CONFIG_PPC64 */
diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c
index 913bfca..6a0bd51 100644
--- a/arch/powerpc/kernel/paca.c
+++ b/arch/powerpc/kernel/paca.c
@@ -36,7 +36,7 @@ static void *__init alloc_paca_data(unsigned long size, unsigned long align,
* which will put its paca in the right place.
*/
if (cpu == boot_cpuid) {
- nid = -1;
+ nid = NUMA_NO_NODE;
memblock_set_bottom_up(true);
} else {
nid = early_cpu_to_node(cpu);
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index 88e4f69..14c33a9 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -132,7 +132,7 @@ struct pci_controller *pcibios_alloc_controller(struct device_node *dev)
int nid = of_node_to_nid(dev);
if (nid < 0 || !node_online(nid))
- nid = -1;
+ nid = NUMA_NO_NODE;
PHB_SET_NODE(phb, nid);
}
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index 3a048e9..77808a2 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -215,7 +215,7 @@ static void initialize_distance_lookup_table(int nid,
*/
static int associativity_to_nid(const __be32 *associativity)
{
- int nid = -1;
+ int nid = NUMA_NO_NODE;
if (min_common_depth == -1)
goto out;
@@ -225,7 +225,7 @@ static int associativity_to_nid(const __be32 *associativity)
/* POWER4 LPAR uses 0xffff as invalid node */
if (nid == 0xffff || nid >= MAX_NUMNODES)
- nid = -1;
+ nid = NUMA_NO_NODE;
if (nid > 0 &&
of_read_number(associativity, 1) >= distance_ref_points_depth) {
@@ -244,7 +244,7 @@ static int associativity_to_nid(const __be32 *associativity)
*/
static int of_node_to_nid_single(struct device_node *device)
{
- int nid = -1;
+ int nid = NUMA_NO_NODE;
const __be32 *tmp;
tmp = of_get_associativity(device);
@@ -256,7 +256,7 @@ static int of_node_to_nid_single(struct device_node *device)
/* Walk the device tree upwards, looking for an associativity id */
int of_node_to_nid(struct device_node *device)
{
- int nid = -1;
+ int nid = NUMA_NO_NODE;
of_node_get(device);
while (device) {
@@ -454,7 +454,7 @@ static int of_drconf_to_nid_single(struct drmem_lmb *lmb)
*/
static int numa_setup_cpu(unsigned long lcpu)
{
- int nid = -1;
+ int nid = NUMA_NO_NODE;
struct device_node *cpu;
/*
@@ -930,7 +930,7 @@ static int hot_add_drconf_scn_to_nid(unsigned long scn_addr)
{
struct drmem_lmb *lmb;
unsigned long lmb_size;
- int nid = -1;
+ int nid = NUMA_NO_NODE;
lmb_size = drmem_lmb_size();
@@ -960,7 +960,7 @@ static int hot_add_drconf_scn_to_nid(unsigned long scn_addr)
static int hot_add_node_scn_to_nid(unsigned long scn_addr)
{
struct device_node *memory;
- int nid = -1;
+ int nid = NUMA_NO_NODE;
for_each_node_by_type(memory, "memory") {
unsigned long start, size;
diff --git a/arch/powerpc/platforms/powernv/memtrace.c b/arch/powerpc/platforms/powernv/memtrace.c
index 84d038e..1ce3bfc 100644
--- a/arch/powerpc/platforms/powernv/memtrace.c
+++ b/arch/powerpc/platforms/powernv/memtrace.c
@@ -223,7 +223,7 @@ static int memtrace_online(void)
ent = &memtrace_array[i];
/* We have onlined this chunk previously */
- if (ent->nid == -1)
+ if (ent->nid == NUMA_NO_NODE)
continue;
/* Remove from io mappings */
@@ -257,7 +257,7 @@ static int memtrace_online(void)
*/
debugfs_remove_recursive(ent->dir);
pr_info("Added trace memory back to node %d\n", ent->nid);
- ent->size = ent->start = ent->nid = -1;
+ ent->size = ent->start = ent->nid = NUMA_NO_NODE;
}
if (ret)
return ret;
diff --git a/arch/sparc/kernel/auxio_32.c b/arch/sparc/kernel/auxio_32.c
index a32d588..39f6c59 100644
--- a/arch/sparc/kernel/auxio_32.c
+++ b/arch/sparc/kernel/auxio_32.c
@@ -120,7 +120,7 @@ void __init auxio_power_probe(void)
node = prom_searchsiblings(node, "obio");
node = prom_getchild(node);
node = prom_searchsiblings(node, "power");
- if (node == 0 || (s32)node == -1)
+ if (node == 0 || (s32)node == NUMA_NO_NODE)
return;
/* Map the power control register. */
diff --git a/arch/sparc/kernel/pci_fire.c b/arch/sparc/kernel/pci_fire.c
index be71ae0..474d3be 100644
--- a/arch/sparc/kernel/pci_fire.c
+++ b/arch/sparc/kernel/pci_fire.c
@@ -416,7 +416,7 @@ static int pci_fire_pbm_init(struct pci_pbm_info *pbm,
struct device_node *dp = op->dev.of_node;
int err;
- pbm->numa_node = -1;
+ pbm->numa_node = NUMA_NO_NODE;
pbm->pci_ops = &sun4u_pci_ops;
pbm->config_space_reg_bits = 12;
diff --git a/arch/sparc/kernel/pci_schizo.c b/arch/sparc/kernel/pci_schizo.c
index 934b97c..87bb231 100644
--- a/arch/sparc/kernel/pci_schizo.c
+++ b/arch/sparc/kernel/pci_schizo.c
@@ -1347,7 +1347,7 @@ static int schizo_pbm_init(struct pci_pbm_info *pbm,
pbm->next = pci_pbm_root;
pci_pbm_root = pbm;
- pbm->numa_node = -1;
+ pbm->numa_node = NUMA_NO_NODE;
pbm->pci_ops = &sun4u_pci_ops;
pbm->config_space_reg_bits = 8;
diff --git a/arch/sparc/kernel/pcic.c b/arch/sparc/kernel/pcic.c
index ee4c9a9..d5fe898 100644
--- a/arch/sparc/kernel/pcic.c
+++ b/arch/sparc/kernel/pcic.c
@@ -476,7 +476,7 @@ static void pcic_map_pci_device(struct linux_pcic *pcic,
unsigned long flags;
int j;
- if (node == 0 || node == -1) {
+ if (node == 0 || node == NUMA_NO_NODE) {
strcpy(namebuf, "???");
} else {
prom_getstring(node, "name", namebuf, 63); namebuf[63] = 0;
@@ -535,7 +535,7 @@ pcic_fill_irq(struct linux_pcic *pcic, struct pci_dev *dev, int node)
int i, ivec;
char namebuf[64];
- if (node == 0 || node == -1) {
+ if (node == 0 || node == NUMA_NO_NODE) {
strcpy(namebuf, "???");
} else {
prom_getstring(node, "name", namebuf, sizeof(namebuf));
@@ -625,7 +625,7 @@ void pcibios_fixup_bus(struct pci_bus *bus)
list_for_each_entry(dev, &bus->devices, bus_list) {
node = pdev_to_pnode(&pcic->pbm, dev);
if(node == 0)
- node = -1;
+ node = NUMA_NO_NODE;
/* cookies */
pcp = pci_devcookie_alloc();
diff --git a/arch/sparc/kernel/psycho_common.c b/arch/sparc/kernel/psycho_common.c
index 81aa91e..dcbf492 100644
--- a/arch/sparc/kernel/psycho_common.c
+++ b/arch/sparc/kernel/psycho_common.c
@@ -454,7 +454,7 @@ void psycho_pbm_init_common(struct pci_pbm_info *pbm, struct platform_device *op
struct device_node *dp = op->dev.of_node;
pbm->name = dp->full_name;
- pbm->numa_node = -1;
+ pbm->numa_node = NUMA_NO_NODE;
pbm->chip_type = chip_type;
pbm->chip_version = of_getintprop_default(dp, "version#", 0);
pbm->chip_revision = of_getintprop_default(dp, "module-revision#", 0);
diff --git a/arch/sparc/kernel/sbus.c b/arch/sparc/kernel/sbus.c
index c133dfc..28a4aa9 100644
--- a/arch/sparc/kernel/sbus.c
+++ b/arch/sparc/kernel/sbus.c
@@ -561,7 +561,7 @@ static void __init sbus_iommu_init(struct platform_device *op)
op->dev.archdata.iommu = iommu;
op->dev.archdata.stc = strbuf;
- op->dev.archdata.numa_node = -1;
+ op->dev.archdata.numa_node = NUMA_NO_NODE;
reg_base = regs + SYSIO_IOMMUREG_BASE;
iommu->iommu_control = reg_base + IOMMU_CONTROL;
diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c
index 3c8aac2..cb1bed1 100644
--- a/arch/sparc/mm/init_64.c
+++ b/arch/sparc/mm/init_64.c
@@ -976,13 +976,13 @@ static u64 __init memblock_nid_range_sun4u(u64 start, u64 end, int *nid)
{
int prev_nid, new_nid;
- prev_nid = -1;
+ prev_nid = NUMA_NO_NODE;
for ( ; start < end; start += PAGE_SIZE) {
for (new_nid = 0; new_nid < num_node_masks; new_nid++) {
struct node_mem_mask *p = &node_masks[new_nid];
if ((start & p->mask) == p->match) {
- if (prev_nid == -1)
+ if (prev_nid == NUMA_NO_NODE)
prev_nid = new_nid;
break;
}
@@ -1208,7 +1208,7 @@ int of_node_to_nid(struct device_node *dp)
md = mdesc_grab();
count = 0;
- nid = -1;
+ nid = NUMA_NO_NODE;
mdesc_for_each_node_by_name(md, grp, "group") {
if (!scan_arcs_for_cfg_handle(md, grp, cfg_handle)) {
nid = count;
diff --git a/arch/sparc/prom/init_32.c b/arch/sparc/prom/init_32.c
index d204701..4c6e540 100644
--- a/arch/sparc/prom/init_32.c
+++ b/arch/sparc/prom/init_32.c
@@ -58,7 +58,7 @@ void __init prom_init(struct linux_romvec *rp)
prom_nodeops = romvec->pv_nodeops;
prom_root_node = prom_getsibling(0);
- if ((prom_root_node == 0) || ((s32)prom_root_node == -1))
+ if ((prom_root_node == 0) || ((s32)prom_root_node == NUMA_NO_NODE))
prom_halt();
if((((unsigned long) prom_nodeops) == 0) ||
diff --git a/arch/sparc/prom/init_64.c b/arch/sparc/prom/init_64.c
index 103aa91..85669c0 100644
--- a/arch/sparc/prom/init_64.c
+++ b/arch/sparc/prom/init_64.c
@@ -36,13 +36,13 @@ void __init prom_init(void *cif_handler)
prom_cif_init(cif_handler);
prom_chosen_node = prom_finddevice(prom_chosen_path);
- if (!prom_chosen_node || (s32)prom_chosen_node == -1)
+ if (!prom_chosen_node || (s32)prom_chosen_node == NUMA_NO_NODE)
prom_halt();
prom_stdout = prom_getint(prom_chosen_node, "stdout");
node = prom_finddevice("/openprom");
- if (!node || (s32)node == -1)
+ if (!node || (s32)node == NUMA_NO_NODE)
prom_halt();
prom_getstring(node, "version", prom_version, sizeof(prom_version));
diff --git a/arch/sparc/prom/tree_32.c b/arch/sparc/prom/tree_32.c
index 0fed893..2d0a204 100644
--- a/arch/sparc/prom/tree_32.c
+++ b/arch/sparc/prom/tree_32.c
@@ -41,11 +41,11 @@ phandle prom_getchild(phandle node)
{
phandle cnode;
- if ((s32)node == -1)
+ if ((s32)node == NUMA_NO_NODE)
return 0;
cnode = __prom_getchild(node);
- if (cnode == 0 || (s32)cnode == -1)
+ if (cnode == 0 || (s32)cnode == NUMA_NO_NODE)
return 0;
return cnode;
@@ -73,11 +73,11 @@ phandle prom_getsibling(phandle node)
{
phandle sibnode;
- if ((s32)node == -1)
+ if ((s32)node == NUMA_NO_NODE)
return 0;
sibnode = __prom_getsibling(node);
- if (sibnode == 0 || (s32)sibnode == -1)
+ if (sibnode == 0 || (s32)sibnode == NUMA_NO_NODE)
return 0;
return sibnode;
@@ -220,7 +220,7 @@ static char *__prom_nextprop(phandle node, char * oprop)
*/
char *prom_nextprop(phandle node, char *oprop, char *buffer)
{
- if (node == 0 || (s32)node == -1)
+ if (node == 0 || (s32)node == NUMA_NO_NODE)
return "";
return __prom_nextprop(node, oprop);
@@ -304,7 +304,7 @@ phandle prom_inst2pkg(int inst)
node = (*romvec->pv_v2devops.v2_inst2pkg)(inst);
restore_current();
spin_unlock_irqrestore(&prom_lock, flags);
- if ((s32)node == -1)
+ if ((s32)node == NUMA_NO_NODE)
return 0;
return node;
}
diff --git a/arch/sparc/prom/tree_64.c b/arch/sparc/prom/tree_64.c
index 989e799..2b4c515 100644
--- a/arch/sparc/prom/tree_64.c
+++ b/arch/sparc/prom/tree_64.c
@@ -44,10 +44,10 @@ phandle prom_getchild(phandle node)
{
phandle cnode;
- if ((s32)node == -1)
+ if ((s32)node == NUMA_NO_NODE)
return 0;
cnode = __prom_getchild(node);
- if ((s32)cnode == -1)
+ if ((s32)cnode == NUMA_NO_NODE)
return 0;
return cnode;
}
@@ -57,10 +57,10 @@ inline phandle prom_getparent(phandle node)
{
phandle cnode;
- if ((s32)node == -1)
+ if ((s32)node == NUMA_NO_NODE)
return 0;
cnode = prom_node_to_node("parent", node);
- if ((s32)cnode == -1)
+ if ((s32)cnode == NUMA_NO_NODE)
return 0;
return cnode;
}
@@ -77,10 +77,10 @@ phandle prom_getsibling(phandle node)
{
phandle sibnode;
- if ((s32)node == -1)
+ if ((s32)node == NUMA_NO_NODE)
return 0;
sibnode = __prom_getsibling(node);
- if ((s32)sibnode == -1)
+ if ((s32)sibnode == NUMA_NO_NODE)
return 0;
return sibnode;
@@ -241,7 +241,7 @@ char *prom_firstprop(phandle node, char *buffer)
unsigned long args[7];
*buffer = 0;
- if ((s32)node == -1)
+ if ((s32)node == NUMA_NO_NODE)
return buffer;
args[0] = (unsigned long) prom_nextprop_name;
@@ -267,7 +267,7 @@ char *prom_nextprop(phandle node, const char *oprop, char *buffer)
unsigned long args[7];
char buf[32];
- if ((s32)node == -1) {
+ if ((s32)node == NUMA_NO_NODE) {
*buffer = 0;
return buffer;
}
@@ -370,7 +370,7 @@ inline phandle prom_inst2pkg(int inst)
p1275_cmd_direct(args);
node = (int) args[4];
- if ((s32)node == -1)
+ if ((s32)node == NUMA_NO_NODE)
return 0;
return node;
}
diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h
index 6629636..dee2a31 100644
--- a/arch/x86/include/asm/pci.h
+++ b/arch/x86/include/asm/pci.h
@@ -141,7 +141,7 @@ cpumask_of_pcibus(const struct pci_bus *bus)
int node;
node = __pcibus_to_node(bus);
- return (node == -1) ? cpu_online_mask :
+ return (node == NUMA_NO_NODE) ? cpu_online_mask :
cpumask_of_node(node);
}
#endif
diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c
index 391f358..3c3378a 100644
--- a/arch/x86/kernel/apic/x2apic_uv_x.c
+++ b/arch/x86/kernel/apic/x2apic_uv_x.c
@@ -1390,7 +1390,7 @@ static void __init build_socket_tables(void)
}
/* Set socket -> node values: */
- lnid = -1;
+ lnid = NUMA_NO_NODE;
for_each_present_cpu(cpu) {
int nid = cpu_to_node(cpu);
int apicid, sockid;
@@ -1521,7 +1521,7 @@ static void __init uv_system_init_hub(void)
new_hub->pnode = 0xffff;
new_hub->numa_blade_id = uv_node_to_blade_id(nodeid);
- new_hub->memory_nid = -1;
+ new_hub->memory_nid = NUMA_NO_NODE;
new_hub->nr_possible_cpus = 0;
new_hub->nr_online_cpus = 0;
}
@@ -1538,7 +1538,7 @@ static void __init uv_system_init_hub(void)
uv_cpu_info_per(cpu)->p_uv_hub_info = uv_hub_info_list(nodeid);
uv_cpu_info_per(cpu)->blade_cpu_id = uv_cpu_hub_info(cpu)->nr_possible_cpus++;
- if (uv_cpu_hub_info(cpu)->memory_nid == -1)
+ if (uv_cpu_hub_info(cpu)->memory_nid == NUMA_NO_NODE)
uv_cpu_hub_info(cpu)->memory_nid = cpu_to_node(cpu);
/* Init memoryless node: */
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index a9134d1..c1d45dc 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -841,7 +841,7 @@ wakeup_secondary_cpu_via_init(int phys_apicid, unsigned long start_eip)
/* reduce the number of lines printed when booting a large cpu count system */
static void announce_cpu(int cpu, int apicid)
{
- static int current_node = -1;
+ static int current_node = NUMA_NO_NODE;
int node = early_cpu_to_node(cpu);
static int width, node_width;
diff --git a/arch/x86/platform/olpc/olpc_dt.c b/arch/x86/platform/olpc/olpc_dt.c
index 24d2175..7098127 100644
--- a/arch/x86/platform/olpc/olpc_dt.c
+++ b/arch/x86/platform/olpc/olpc_dt.c
@@ -29,10 +29,10 @@ static phandle __init olpc_dt_getsibling(phandle node)
const void *args[] = { (void *)node };
void *res[] = { &node };
- if ((s32)node == -1)
+ if ((s32)node == NUMA_NO_NODE)
return 0;
- if (olpc_ofw("peer", args, res) || (s32)node == -1)
+ if (olpc_ofw("peer", args, res) || (s32)node == NUMA_NO_NODE)
return 0;
return node;
@@ -43,10 +43,10 @@ static phandle __init olpc_dt_getchild(phandle node)
const void *args[] = { (void *)node };
void *res[] = { &node };
- if ((s32)node == -1)
+ if ((s32)node == NUMA_NO_NODE)
return 0;
- if (olpc_ofw("child", args, res) || (s32)node == -1) {
+ if (olpc_ofw("child", args, res) || (s32)node == NUMA_NO_NODE) {
pr_err("PROM: %s: fetching child failed!\n", __func__);
return 0;
}
@@ -60,7 +60,7 @@ static int __init olpc_dt_getproplen(phandle node, const char *prop)
int len;
void *res[] = { &len };
- if ((s32)node == -1)
+ if ((s32)node == NUMA_NO_NODE)
return -1;
if (olpc_ofw("getproplen", args, res)) {
@@ -100,7 +100,7 @@ static int __init olpc_dt_nextprop(phandle node, char *prev, char *buf)
buf[0] = '\0';
- if ((s32)node == -1)
+ if ((s32)node == NUMA_NO_NODE)
return -1;
if (olpc_ofw("nextprop", args, res) || success != 1)
@@ -115,7 +115,7 @@ static int __init olpc_dt_pkg2path(phandle node, char *buf,
const void *args[] = { (void *)node, buf, (void *)buflen };
void *res[] = { len };
- if ((s32)node == -1)
+ if ((s32)node == NUMA_NO_NODE)
return -1;
if (olpc_ofw("package-to-path", args, res) || *len < 1)
@@ -176,7 +176,7 @@ static phandle __init olpc_dt_finddevice(const char *path)
return 0;
}
- if ((s32) node == -1)
+ if ((s32) node == NUMA_NO_NODE)
return 0;
return node;
diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c
index a7daa8a..b889452 100644
--- a/drivers/block/mtip32xx/mtip32xx.c
+++ b/drivers/block/mtip32xx/mtip32xx.c
@@ -4084,9 +4084,9 @@ static int get_least_used_cpu_on_node(int node)
/* Helper for selecting a node in round robin mode */
static inline int mtip_get_next_rr_node(void)
{
- static int next_node = -1;
+ static int next_node = NUMA_NO_NODE;
- if (next_node == -1) {
+ if (next_node == NUMA_NO_NODE) {
next_node = first_online_node;
return next_node;
}
diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
index f1a441ab..1aeefc7 100644
--- a/drivers/dma/dmaengine.c
+++ b/drivers/dma/dmaengine.c
@@ -386,7 +386,8 @@ EXPORT_SYMBOL(dma_issue_pending_all);
static bool dma_chan_is_local(struct dma_chan *chan, int cpu)
{
int node = dev_to_node(chan->device->dev);
- return node == -1 || cpumask_test_cpu(cpu, cpumask_of_node(node));
+ return node == NUMA_NO_NODE ||
+ cpumask_test_cpu(cpu, cpumask_of_node(node));
}
/**
diff --git a/drivers/infiniband/hw/hfi1/affinity.c b/drivers/infiniband/hw/hfi1/affinity.c
index 2baf38c..3e8acb8 100644
--- a/drivers/infiniband/hw/hfi1/affinity.c
+++ b/drivers/infiniband/hw/hfi1/affinity.c
@@ -777,7 +777,7 @@ void hfi1_dev_affinity_clean_up(struct hfi1_devdata *dd)
_dev_comp_vect_cpu_mask_clean_up(dd, entry);
unlock:
mutex_unlock(&node_affinity.lock);
- dd->node = -1;
+ dd->node = NUMA_NO_NODE;
}
/*
diff --git a/drivers/infiniband/hw/hfi1/init.c b/drivers/infiniband/hw/hfi1/init.c
index 0904490..0bf4577 100644
--- a/drivers/infiniband/hw/hfi1/init.c
+++ b/drivers/infiniband/hw/hfi1/init.c
@@ -1303,7 +1303,7 @@ static struct hfi1_devdata *hfi1_alloc_devdata(struct pci_dev *pdev,
dd->unit = ret;
list_add(&dd->list, &hfi1_dev_list);
}
- dd->node = -1;
+ dd->node = NUMA_NO_NODE;
spin_unlock_irqrestore(&hfi1_devs_lock, flags);
idr_preload_end();
diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c
index d9c748b..86a9c19 100644
--- a/drivers/iommu/dmar.c
+++ b/drivers/iommu/dmar.c
@@ -477,7 +477,7 @@ static int dmar_parse_one_rhsa(struct acpi_dmar_header *header, void *arg)
int node = acpi_map_pxm_to_node(rhsa->proximity_domain);
if (!node_online(node))
- node = -1;
+ node = NUMA_NO_NODE;
drhd->iommu->node = node;
return 0;
}
@@ -1062,7 +1062,7 @@ static int alloc_iommu(struct dmar_drhd_unit *drhd)
iommu->msagaw = msagaw;
iommu->segment = drhd->segment;
- iommu->node = -1;
+ iommu->node = NUMA_NO_NODE;
ver = readl(iommu->reg + DMAR_VER_REG);
pr_info("%s: reg_base_addr %llx ver %d:%d cap %llx ecap %llx\n",
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index f3ccf02..9f6fb13 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -1772,7 +1772,7 @@ static struct dmar_domain *alloc_domain(int flags)
return NULL;
memset(domain, 0, sizeof(*domain));
- domain->nid = -1;
+ domain->nid = NUMA_NO_NODE;
domain->flags = flags;
domain->has_iotlb_device = false;
INIT_LIST_HEAD(&domain->devices);
diff --git a/drivers/misc/sgi-xp/xpc_uv.c b/drivers/misc/sgi-xp/xpc_uv.c
index 0441abe..eef36dd 100644
--- a/drivers/misc/sgi-xp/xpc_uv.c
+++ b/drivers/misc/sgi-xp/xpc_uv.c
@@ -61,7 +61,7 @@ static struct xpc_heartbeat_uv *xpc_heartbeat_uv;
XPC_NOTIFY_MSG_SIZE_UV)
#define XPC_NOTIFY_IRQ_NAME "xpc_notify"
-static int xpc_mq_node = -1;
+static int xpc_mq_node = NUMA_NO_NODE;
static struct xpc_gru_mq_uv *xpc_activate_mq_uv;
static struct xpc_gru_mq_uv *xpc_notify_mq_uv;
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 113b38e..4fae85c 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -6414,7 +6414,7 @@ int ixgbe_setup_tx_resources(struct ixgbe_ring *tx_ring)
{
struct device *dev = tx_ring->dev;
int orig_node = dev_to_node(dev);
- int ring_node = -1;
+ int ring_node = NUMA_NO_NODE;
int size;
size = sizeof(struct ixgbe_tx_buffer) * tx_ring->count;
@@ -6508,7 +6508,7 @@ int ixgbe_setup_rx_resources(struct ixgbe_adapter *adapter,
{
struct device *dev = rx_ring->dev;
int orig_node = dev_to_node(dev);
- int ring_node = -1;
+ int ring_node = NUMA_NO_NODE;
int size;
size = sizeof(struct ixgbe_rx_buffer) * rx_ring->count;
diff --git a/init/init_task.c b/init/init_task.c
index 5aebe3b..6641836 100644
--- a/init/init_task.c
+++ b/init/init_task.c
@@ -154,7 +154,7 @@ struct task_struct init_task
.vtime.state = VTIME_SYS,
#endif
#ifdef CONFIG_NUMA_BALANCING
- .numa_preferred_nid = -1,
+ .numa_preferred_nid = NUMA_NO_NODE,
.numa_group = NULL,
.numa_faults = NULL,
#endif
diff --git a/kernel/kthread.c b/kernel/kthread.c
index 087d18d..77f3d94 100644
--- a/kernel/kthread.c
+++ b/kernel/kthread.c
@@ -675,7 +675,7 @@ __kthread_create_worker(int cpu, unsigned int flags,
{
struct kthread_worker *worker;
struct task_struct *task;
- int node = -1;
+ int node = NUMA_NO_NODE;
worker = kzalloc(sizeof(*worker), GFP_KERNEL);
if (!worker)
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index ee271bb..d830fa7 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -1161,7 +1161,7 @@ void init_numa_balancing(unsigned long clone_flags, struct task_struct *p)
/* New address space, reset the preferred nid */
if (!(clone_flags & CLONE_VM)) {
- p->numa_preferred_nid = -1;
+ p->numa_preferred_nid = NUMA_NO_NODE;
return;
}
@@ -1181,13 +1181,13 @@ void init_numa_balancing(unsigned long clone_flags, struct task_struct *p)
static void account_numa_enqueue(struct rq *rq, struct task_struct *p)
{
- rq->nr_numa_running += (p->numa_preferred_nid != -1);
+ rq->nr_numa_running += (p->numa_preferred_nid != NUMA_NO_NODE);
rq->nr_preferred_running += (p->numa_preferred_nid == task_node(p));
}
static void account_numa_dequeue(struct rq *rq, struct task_struct *p)
{
- rq->nr_numa_running -= (p->numa_preferred_nid != -1);
+ rq->nr_numa_running -= (p->numa_preferred_nid != NUMA_NO_NODE);
rq->nr_preferred_running -= (p->numa_preferred_nid == task_node(p));
}
@@ -1401,7 +1401,7 @@ bool should_numa_migrate_memory(struct task_struct *p, struct page * page,
* two full passes of the "multi-stage node selection" test that is
* executed below.
*/
- if ((p->numa_preferred_nid == -1 || p->numa_scan_seq <= 4) &&
+ if ((p->numa_preferred_nid == NUMA_NO_NODE || p->numa_scan_seq <= 4) &&
(cpupid_pid_unset(last_cpupid) || cpupid_match_pid(p, last_cpupid)))
return true;
@@ -1849,7 +1849,7 @@ static void numa_migrate_preferred(struct task_struct *p)
unsigned long interval = HZ;
/* This task has no NUMA fault statistics yet */
- if (unlikely(p->numa_preferred_nid == -1 || !p->numa_faults))
+ if (unlikely(p->numa_preferred_nid == NUMA_NO_NODE || !p->numa_faults))
return;
/* Periodically retry migrating the task to the preferred node */
@@ -2096,7 +2096,7 @@ static int preferred_group_nid(struct task_struct *p, int nid)
static void task_numa_placement(struct task_struct *p)
{
- int seq, nid, max_nid = -1;
+ int seq, nid, max_nid = NUMA_NO_NODE;
unsigned long max_faults = 0;
unsigned long fault_types[2] = { 0, 0 };
unsigned long total_faults;
@@ -2639,7 +2639,8 @@ static void update_scan_period(struct task_struct *p, int new_cpu)
* the preferred node.
*/
if (dst_nid == p->numa_preferred_nid ||
- (p->numa_preferred_nid != -1 && src_nid != p->numa_preferred_nid))
+ (p->numa_preferred_nid != NUMA_NO_NODE &&
+ src_nid != p->numa_preferred_nid))
return;
}
diff --git a/lib/cpumask.c b/lib/cpumask.c
index 8d666ab..a089c3f 100644
--- a/lib/cpumask.c
+++ b/lib/cpumask.c
@@ -206,7 +206,7 @@ unsigned int cpumask_local_spread(unsigned int i, int node)
/* Wrap: we always want a cpu. */
i %= num_online_cpus();
- if (node == -1) {
+ if (node == NUMA_NO_NODE) {
for_each_cpu(cpu, cpu_online_mask)
if (i-- == 0)
return cpu;
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index 55478ab..5ccf89e 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -1480,7 +1480,7 @@ vm_fault_t do_huge_pmd_numa_page(struct vm_fault *vmf, pmd_t pmd)
struct anon_vma *anon_vma = NULL;
struct page *page;
unsigned long haddr = vmf->address & HPAGE_PMD_MASK;
- int page_nid = -1, this_nid = numa_node_id();
+ int page_nid = NUMA_NO_NODE, this_nid = numa_node_id();
int target_nid, last_cpupid = -1;
bool page_locked;
bool migrated = false;
@@ -1526,7 +1526,7 @@ vm_fault_t do_huge_pmd_numa_page(struct vm_fault *vmf, pmd_t pmd)
*/
page_locked = trylock_page(page);
target_nid = mpol_misplaced(page, vma, haddr);
- if (target_nid == -1) {
+ if (target_nid == NUMA_NO_NODE) {
/* If the page was locked, there are no parallel migrations */
if (page_locked)
goto clear_pmdnuma;
@@ -1534,7 +1534,7 @@ vm_fault_t do_huge_pmd_numa_page(struct vm_fault *vmf, pmd_t pmd)
/* Migration could have started since the pmd_trans_migrating check */
if (!page_locked) {
- page_nid = -1;
+ page_nid = NUMA_NO_NODE;
if (!get_page_unless_zero(page))
goto out_unlock;
spin_unlock(vmf->ptl);
@@ -1556,14 +1556,14 @@ vm_fault_t do_huge_pmd_numa_page(struct vm_fault *vmf, pmd_t pmd)
if (unlikely(!pmd_same(pmd, *vmf->pmd))) {
unlock_page(page);
put_page(page);
- page_nid = -1;
+ page_nid = NUMA_NO_NODE;
goto out_unlock;
}
/* Bail if we fail to protect against THP splits for any reason */
if (unlikely(!anon_vma)) {
put_page(page);
- page_nid = -1;
+ page_nid = NUMA_NO_NODE;
goto clear_pmdnuma;
}
@@ -1625,7 +1625,7 @@ vm_fault_t do_huge_pmd_numa_page(struct vm_fault *vmf, pmd_t pmd)
if (anon_vma)
page_unlock_anon_vma_read(anon_vma);
- if (page_nid != -1)
+ if (page_nid != NUMA_NO_NODE)
task_numa_fault(last_cpupid, page_nid, HPAGE_PMD_NR,
flags);
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index c007fb5..b769db7 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -887,7 +887,7 @@ static struct page *dequeue_huge_page_nodemask(struct hstate *h, gfp_t gfp_mask,
struct zonelist *zonelist;
struct zone *zone;
struct zoneref *z;
- int node = -1;
+ int node = NUMA_NO_NODE;
zonelist = node_zonelist(nid, gfp_mask);
diff --git a/mm/ksm.c b/mm/ksm.c
index 5b0894b..d5f8834 100644
--- a/mm/ksm.c
+++ b/mm/ksm.c
@@ -597,7 +597,7 @@ static struct stable_node *alloc_stable_node_chain(struct stable_node *dup,
chain->chain_prune_time = jiffies;
chain->rmap_hlist_len = STABLE_NODE_CHAIN;
#if defined (CONFIG_DEBUG_VM) && defined(CONFIG_NUMA)
- chain->nid = -1; /* debug */
+ chain->nid = NUMA_NO_NODE; /* debug */
#endif
ksm_stable_node_chains++;
diff --git a/mm/memory.c b/mm/memory.c
index 4ad2d29..c0e0348 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -3564,7 +3564,7 @@ static vm_fault_t do_numa_page(struct vm_fault *vmf)
{
struct vm_area_struct *vma = vmf->vma;
struct page *page = NULL;
- int page_nid = -1;
+ int page_nid = NUMA_NO_NODE;
int last_cpupid;
int target_nid;
bool migrated = false;
@@ -3631,7 +3631,7 @@ static vm_fault_t do_numa_page(struct vm_fault *vmf)
target_nid = numa_migrate_prep(page, vma, vmf->address, page_nid,
&flags);
pte_unmap_unlock(vmf->pte, vmf->ptl);
- if (target_nid == -1) {
+ if (target_nid == NUMA_NO_NODE) {
put_page(page);
goto out;
}
@@ -3645,7 +3645,7 @@ static vm_fault_t do_numa_page(struct vm_fault *vmf)
flags |= TNF_MIGRATE_FAIL;
out:
- if (page_nid != -1)
+ if (page_nid != NUMA_NO_NODE)
task_numa_fault(last_cpupid, page_nid, 1, flags);
return 0;
}
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index 2b2b3cc..70e02f8 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -688,9 +688,9 @@ static void node_states_check_changes_online(unsigned long nr_pages,
{
int nid = zone_to_nid(zone);
- arg->status_change_nid = -1;
- arg->status_change_nid_normal = -1;
- arg->status_change_nid_high = -1;
+ arg->status_change_nid = NUMA_NO_NODE;
+ arg->status_change_nid_normal = NUMA_NO_NODE;
+ arg->status_change_nid_high = NUMA_NO_NODE;
if (!node_state(nid, N_MEMORY))
arg->status_change_nid = nid;
@@ -1484,9 +1484,9 @@ static void node_states_check_changes_offline(unsigned long nr_pages,
unsigned long present_pages = 0;
enum zone_type zt;
- arg->status_change_nid = -1;
- arg->status_change_nid_normal = -1;
- arg->status_change_nid_high = -1;
+ arg->status_change_nid = NUMA_NO_NODE;
+ arg->status_change_nid_normal = NUMA_NO_NODE;
+ arg->status_change_nid_high = NUMA_NO_NODE;
/*
* Check whether node_states[N_NORMAL_MEMORY] will be changed.
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index 5837a06..e4f8248 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -2278,7 +2278,7 @@ int mpol_misplaced(struct page *page, struct vm_area_struct *vma, unsigned long
unsigned long pgoff;
int thiscpu = raw_smp_processor_id();
int thisnid = cpu_to_node(thiscpu);
- int polnid = -1;
+ int polnid = NUMA_NO_NODE;
int ret = -1;
pol = get_vma_policy(vma, addr);
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index a919ba5..9d38d9c 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -5846,7 +5846,7 @@ int __meminit __early_pfn_to_nid(unsigned long pfn,
return state->last_nid;
nid = memblock_search_pfn_nid(pfn, &start_pfn, &end_pfn);
- if (nid != -1) {
+ if (nid != NUMA_NO_NODE) {
state->last_start = start_pfn;
state->last_end = end_pfn;
state->last_nid = nid;
@@ -6607,7 +6607,7 @@ unsigned long __init node_map_pfn_alignment(void)
{
unsigned long accl_mask = 0, last_end = 0;
unsigned long start, end, mask;
- int last_nid = -1;
+ int last_nid = NUMA_NO_NODE;
int i, nid;
for_each_mem_pfn_range(i, MAX_NUMNODES, &start, &end, &nid) {
diff --git a/mm/page_ext.c b/mm/page_ext.c
index ae44f7a..dfb0206 100644
--- a/mm/page_ext.c
+++ b/mm/page_ext.c
@@ -300,7 +300,7 @@ static int __meminit online_page_ext(unsigned long start_pfn,
start = SECTION_ALIGN_DOWN(start_pfn);
end = SECTION_ALIGN_UP(start_pfn + nr_pages);
- if (nid == -1) {
+ if (nid == NUMA_NO_NODE) {
/*
* In this case, "nid" already exists and contains valid memory.
* "start_pfn" passed to us is a pfn which is an arg for
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index 6ac9198..af3a746 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -3625,7 +3625,7 @@ static int pktgen_add_device(struct pktgen_thread *t, const char *ifname)
pkt_dev->svlan_cfi = 0;
pkt_dev->svlan_id = 0xffff;
pkt_dev->burst = 1;
- pkt_dev->node = -1;
+ pkt_dev->node = NUMA_NO_NODE;
err = pktgen_setup_dev(t->net, pkt_dev, ifname);
if (err)
diff --git a/net/qrtr/qrtr.c b/net/qrtr/qrtr.c
index 86e1e37..0c56ae2 100644
--- a/net/qrtr/qrtr.c
+++ b/net/qrtr/qrtr.c
@@ -101,7 +101,7 @@ static inline struct qrtr_sock *qrtr_sk(struct sock *sk)
return container_of(sk, struct qrtr_sock, sk);
}
-static unsigned int qrtr_local_nid = -1;
+static unsigned int qrtr_local_nid = NUMA_NO_NODE;
/* for node ids */
static RADIX_TREE(qrtr_nodes, GFP_KERNEL);
diff --git a/tools/perf/bench/numa.c b/tools/perf/bench/numa.c
index 4419551..e0ad5f1 100644
--- a/tools/perf/bench/numa.c
+++ b/tools/perf/bench/numa.c
@@ -298,7 +298,7 @@ static cpu_set_t bind_to_node(int target_node)
CPU_ZERO(&mask);
- if (target_node == -1) {
+ if (target_node == NUMA_NO_NODE) {
for (cpu = 0; cpu < g->p.nr_cpus; cpu++)
CPU_SET(cpu, &mask);
} else {
@@ -339,7 +339,7 @@ static void bind_to_memnode(int node)
unsigned long nodemask;
int ret;
- if (node == -1)
+ if (node == NUMA_NO_NODE)
return;
BUG_ON(g->p.nr_nodes > (int)sizeof(nodemask)*8);
@@ -1363,7 +1363,7 @@ static void init_thread_data(void)
int cpu;
/* Allow all nodes by default: */
- td->bind_node = -1;
+ td->bind_node = NUMA_NO_NODE;
/* Allow all CPUs by default: */
CPU_ZERO(&td->bind_cpumask);
--
2.7.4
^ permalink raw reply related
* [RFC PATCH] net: macb: Apply RXUBR workaround only to versions with errata
From: Harini Katakam @ 2018-11-23 9:59 UTC (permalink / raw)
To: nicolas.ferre, davem
Cc: netdev, linux-kernel, michal.simek, harinikatakamlinux,
harini.katakam
The interrupt handler contains a workaround for RX hang applicable
to Zynq and AT91 only. Subsequent versions do not need this
workaround. This workaround unecessarily reset RX whenever RX used
bit read is observed, which can be often under heavy traffic.Hence
introduce an errata field and a check to enable this workaround.
Signed-off-by: Harini Katakam <harini.katakam@xilinx.com>
---
Note: Enabled the errata in zynq and at91 configs only.
Please advise if any other versions are affected by this errata.
drivers/net/ethernet/cadence/macb.h | 6 ++++++
drivers/net/ethernet/cadence/macb_main.c | 9 +++++++--
2 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h
index 3d45f4c..f6903d6 100644
--- a/drivers/net/ethernet/cadence/macb.h
+++ b/drivers/net/ethernet/cadence/macb.h
@@ -648,6 +648,9 @@
#define MACB_CAPS_SG_DISABLED 0x40000000
#define MACB_CAPS_MACB_IS_GEM 0x80000000
+/* Errata mask bits */
+#define MACB_ERRATA_RXLOCKUP 0x00000001
+
/* LSO settings */
#define MACB_LSO_UFO_ENABLE 0x01
#define MACB_LSO_TSO_ENABLE 0x02
@@ -1085,6 +1088,7 @@ struct macb_config {
struct clk **rx_clk);
int (*init)(struct platform_device *pdev);
int jumbo_max_len;
+ u32 errata;
};
struct tsu_incr {
@@ -1214,6 +1218,8 @@ struct macb {
int rx_bd_rd_prefetch;
int tx_bd_rd_prefetch;
+
+ u32 errata;
};
#ifdef CONFIG_MACB_USE_HWSTAMP
diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
index 1d86b4d..f0bb8a4 100644
--- a/drivers/net/ethernet/cadence/macb_main.c
+++ b/drivers/net/ethernet/cadence/macb_main.c
@@ -1379,7 +1379,8 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id)
* the at91 manual, section 41.3.1 or the Zynq manual
* section 16.7.4 for details.
*/
- if (status & MACB_BIT(RXUBR)) {
+ if ((bp->errata & MACB_ERRATA_RXLOCKUP) &&
+ (status & MACB_BIT(RXUBR))) {
ctrl = macb_readl(bp, NCR);
macb_writel(bp, NCR, ctrl & ~MACB_BIT(RE));
wmb();
@@ -3835,6 +3836,7 @@ static const struct macb_config at91sam9260_config = {
.caps = MACB_CAPS_USRIO_HAS_CLKEN | MACB_CAPS_USRIO_DEFAULT_IS_MII_GMII,
.clk_init = macb_clk_init,
.init = macb_init,
+ .errata = MACB_ERRATA_RXLOCKUP,
};
static const struct macb_config sama5d3macb_config = {
@@ -3900,6 +3902,7 @@ static const struct macb_config zynq_config = {
.dma_burst_length = 16,
.clk_init = macb_clk_init,
.init = macb_init,
+ .errata = MACB_ERRATA_RXLOCKUP,
};
static const struct of_device_id macb_dt_ids[] = {
@@ -4005,8 +4008,10 @@ static int macb_probe(struct platform_device *pdev)
bp->hclk = hclk;
bp->tx_clk = tx_clk;
bp->rx_clk = rx_clk;
- if (macb_config)
+ if (macb_config) {
bp->jumbo_max_len = macb_config->jumbo_max_len;
+ bp->errata = macb_config->errata;
+ }
bp->wol = 0;
if (of_get_property(np, "magic-packet", NULL))
--
2.7.4
^ permalink raw reply related
* [PATCH net-next 00/12] switchdev: Convert switchdev_port_obj_{add,del}() to notifiers
From: Petr Machata @ 2018-11-22 23:27 UTC (permalink / raw)
To: netdev@vger.kernel.org, devel@driverdev.osuosl.org
Cc: Jiri Pirko, Ido Schimmel, davem@davemloft.net,
alexandre.belloni@bootlin.com, ruxandra.radulescu@nxp.com,
ioana.ciornei@nxp.com, gregkh@linuxfoundation.org,
ivecera@redhat.com, andrew@lunn.ch,
vivien.didelot@savoirfairelinux.com, f.fainelli@gmail.com
An offloading driver may need to have access to switchdev events on
ports that aren't directly under its control. An example is a VXLAN port
attached to a bridge offloaded by a driver. The driver needs to know
about VLANs configured on the VXLAN device. However the VXLAN device
isn't stashed between the bridge and a front-panel-port device (such as
is the case e.g. for LAG devices), so the usual switchdev ops don't
reach the driver.
VXLAN is likely not the only device type like this: in theory any L2
tunnel device that needs offloading will prompt requirement of this
sort.
A way to fix this is to give up the notion of port object addition /
deletion as a switchdev operation, which assumes somewhat tight coupling
between the message producer and consumer. And instead send the message
over a notifier chain.
The series starts with a clean-up patch #1, where
SWITCHDEV_OBJ_PORT_{VLAN, MDB}() are fixed up to lift the constraint
that the passed-in argument be a simple variable named "obj".
switchdev_port_obj_add and _del are invoked in a context that permits
blocking. Not only that, at least for the VLAN notification, being able
to signal failure is actually important. Therefore introduce a new
blocking notifier chain that the new events will be sent on. That's done
in patch #2. Retain the current (atomic) notifier chain for the
preexisting notifications.
In patch #3, introduce two new switchdev notifier types,
SWITCHDEV_PORT_OBJ_ADD and SWITCHDEV_PORT_OBJ_DEL. These notifier types
communicate the same event as the corresponding switchdev op, except in
a form of a notification. struct switchdev_notifier_port_obj_info was
added to carry the fields that correspond to the switchdev op arguments.
An additional field, handled, will be used to communicate back to
switchdev that the event has reached an interested party, which will be
important for the two-phase commit.
In patches #4, #5, and #7, rocker, DSA resp. ethsw are updated to
subscribe to the switchdev blocking notifier chain, and handle the new
notifier types. #6 introduces a helper to determine whether a
netdevice corresponds to a front panel port.
What these three drivers have in common is that their ports don't
support any uppers besides bridge. That makes it possible to ignore any
notifiers that don't reference a front-panel port device, because they
are certainly out of scope.
Unlike the previous three, mlxsw and ocelot drivers admit stacked
devices as uppers. While the current switchdev code recursively descends
through layers of lower devices, eventually calling the op on a
front-panel port device, the notifier would reference a stacking device
that's one of front-panel ports uppers. The filtering is thus more
complex.
For ocelot, such iteration is currently pretty much required, because
there's no bookkeeping of LAG devices. mlxsw does keep the list of LAGs,
however it iterates the lower devices anyway when deciding whether an
event on a tunnel device pertains to the driver or not.
Therefore this patch set instead introduces, in patch #8, a helper to
iterate through lowers, much like the current switchdev code does,
looking for devices that match a given predicate.
Then in patches #9 and #10, first mlxsw and then ocelot are updated to
dispatch the newly-added notifier types to the preexisting
port_obj_add/_del handlers. The dispatch is done via the new helper, to
recursively descend through lower devices.
Finally in patch #11, the actual switch is made, retiring the current
SDO-based code in favor of a notifier.
Now that the event is distributed through a notifier, the explicit
netdevice check in rocker, DSA and ethsw doesn't let through any events
except those done on a front-panel port itself. It is therefore
unnecessary to check in VLAN-handling code whether a VLAN was added to
the bridge itself: such events will simply be ignored much sooner.
Therefore remove it in patch #12.
Petr Machata (12):
switchdev: SWITCHDEV_OBJ_PORT_{VLAN, MDB}(): Sanitize
switchdev: Add a blocking notifier chain
switchdev: Add SWITCHDEV_PORT_OBJ_ADD, SWITCHDEV_PORT_OBJ_DEL
rocker: Handle SWITCHDEV_PORT_OBJ_ADD/_DEL
net: dsa: slave: Handle SWITCHDEV_PORT_OBJ_ADD/_DEL
staging: fsl-dpaa2: ethsw: Introduce ethsw_port_dev_check()
staging: fsl-dpaa2: ethsw: Handle SWITCHDEV_PORT_OBJ_ADD/_DEL
switchdev: Add helpers to aid traversal through lower devices
mlxsw: spectrum_switchdev: Handle SWITCHDEV_PORT_OBJ_ADD/_DEL
ocelot: Handle SWITCHDEV_PORT_OBJ_ADD/_DEL
switchdev: Replace port obj add/del SDO with a notification
rocker, dsa, ethsw: Don't filter VLAN events on bridge itself
.../ethernet/mellanox/mlxsw/spectrum_switchdev.c | 47 ++++-
drivers/net/ethernet/mscc/ocelot.c | 30 +++-
drivers/net/ethernet/mscc/ocelot.h | 1 +
drivers/net/ethernet/mscc/ocelot_board.c | 3 +
drivers/net/ethernet/rocker/rocker_main.c | 60 ++++++-
drivers/staging/fsl-dpaa2/ethsw/ethsw.c | 68 +++++++-
include/net/switchdev.h | 87 ++++++++--
net/dsa/port.c | 3 -
net/dsa/slave.c | 58 ++++++-
net/switchdev/switchdev.c | 193 ++++++++++++++++-----
10 files changed, 474 insertions(+), 76 deletions(-)
--
2.4.11
^ permalink raw reply
* [PATCH net-next 01/12] switchdev: SWITCHDEV_OBJ_PORT_{VLAN, MDB}(): Sanitize
From: Petr Machata @ 2018-11-22 23:28 UTC (permalink / raw)
To: netdev@vger.kernel.org, devel@driverdev.osuosl.org
Cc: Jiri Pirko, Ido Schimmel, davem@davemloft.net,
alexandre.belloni@bootlin.com, ruxandra.radulescu@nxp.com,
ioana.ciornei@nxp.com, gregkh@linuxfoundation.org,
ivecera@redhat.com, andrew@lunn.ch,
vivien.didelot@savoirfairelinux.com, f.fainelli@gmail.com
In-Reply-To: <cover.1542927590.git.petrm@mellanox.com>
The two macros SWITCHDEV_OBJ_PORT_VLAN() and SWITCHDEV_OBJ_PORT_MDB()
expand to a container_of() call, yielding an appropriate container of
their sole argument. However, due to a name collision, the first
argument, i.e. the contained object pointer, is not the only one to get
expanded. The third argument, which is a structure member name, and
should be kept literal, gets expanded as well. The only safe way to use
these two macros is therefore to name the local variable passed to them
"obj".
To fix this, rename the sole argument of the two macros from
"obj" (which collides with the member name) to "OBJ". Additionally,
instead of passing "OBJ" to container_of() verbatim, parenthesize it, so
that a comma in the passed-in expression doesn't pollute the
container_of() invocation.
Signed-off-by: Petr Machata <petrm@mellanox.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
Reviewed-by: Ido Schimmel <idosch@mellanox.com>
---
include/net/switchdev.h | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/include/net/switchdev.h b/include/net/switchdev.h
index 7b371e7c4bc6..dd969224a9b9 100644
--- a/include/net/switchdev.h
+++ b/include/net/switchdev.h
@@ -95,8 +95,8 @@ struct switchdev_obj_port_vlan {
u16 vid_end;
};
-#define SWITCHDEV_OBJ_PORT_VLAN(obj) \
- container_of(obj, struct switchdev_obj_port_vlan, obj)
+#define SWITCHDEV_OBJ_PORT_VLAN(OBJ) \
+ container_of((OBJ), struct switchdev_obj_port_vlan, obj)
/* SWITCHDEV_OBJ_ID_PORT_MDB */
struct switchdev_obj_port_mdb {
@@ -105,8 +105,8 @@ struct switchdev_obj_port_mdb {
u16 vid;
};
-#define SWITCHDEV_OBJ_PORT_MDB(obj) \
- container_of(obj, struct switchdev_obj_port_mdb, obj)
+#define SWITCHDEV_OBJ_PORT_MDB(OBJ) \
+ container_of((OBJ), struct switchdev_obj_port_mdb, obj)
void switchdev_trans_item_enqueue(struct switchdev_trans *trans,
void *data, void (*destructor)(void const *),
--
2.4.11
^ permalink raw reply related
* [PATCH net-next 02/12] switchdev: Add a blocking notifier chain
From: Petr Machata @ 2018-11-22 23:28 UTC (permalink / raw)
To: netdev@vger.kernel.org, devel@driverdev.osuosl.org
Cc: Jiri Pirko, Ido Schimmel, davem@davemloft.net,
alexandre.belloni@bootlin.com, ruxandra.radulescu@nxp.com,
ioana.ciornei@nxp.com, gregkh@linuxfoundation.org,
ivecera@redhat.com, andrew@lunn.ch,
vivien.didelot@savoirfairelinux.com, f.fainelli@gmail.com
In-Reply-To: <cover.1542927590.git.petrm@mellanox.com>
In general one can't assume that a switchdev notifier is called in a
non-atomic context, and correspondingly, the switchdev notifier chain is
an atomic one.
However, port object addition and deletion messages are delivered from a
process context. Even the MDB addition messages, whose delivery is
scheduled from atomic context, are queued and the delivery itself takes
place in blocking context. For VLAN messages in particular, keeping the
blocking nature is important for error reporting.
Therefore introduce a blocking notifier chain and related service
functions to distribute the notifications for which a blocking context
can be assumed.
Signed-off-by: Petr Machata <petrm@mellanox.com>
Reviewed-by: Jiri Pirko <jiri@mellanox.com>
Reviewed-by: Ido Schimmel <idosch@mellanox.com>
---
include/net/switchdev.h | 27 +++++++++++++++++++++++++++
net/switchdev/switchdev.c | 26 ++++++++++++++++++++++++++
2 files changed, 53 insertions(+)
diff --git a/include/net/switchdev.h b/include/net/switchdev.h
index dd969224a9b9..e021b67b9b32 100644
--- a/include/net/switchdev.h
+++ b/include/net/switchdev.h
@@ -182,10 +182,17 @@ int switchdev_port_obj_add(struct net_device *dev,
const struct switchdev_obj *obj);
int switchdev_port_obj_del(struct net_device *dev,
const struct switchdev_obj *obj);
+
int register_switchdev_notifier(struct notifier_block *nb);
int unregister_switchdev_notifier(struct notifier_block *nb);
int call_switchdev_notifiers(unsigned long val, struct net_device *dev,
struct switchdev_notifier_info *info);
+
+int register_switchdev_blocking_notifier(struct notifier_block *nb);
+int unregister_switchdev_blocking_notifier(struct notifier_block *nb);
+int call_switchdev_blocking_notifiers(unsigned long val, struct net_device *dev,
+ struct switchdev_notifier_info *info);
+
void switchdev_port_fwd_mark_set(struct net_device *dev,
struct net_device *group_dev,
bool joining);
@@ -241,6 +248,26 @@ static inline int call_switchdev_notifiers(unsigned long val,
return NOTIFY_DONE;
}
+static inline int
+register_switchdev_blocking_notifier(struct notifier_block *nb)
+{
+ return 0;
+}
+
+static inline int
+unregister_switchdev_blocking_notifier(struct notifier_block *nb)
+{
+ return 0;
+}
+
+static inline int
+call_switchdev_blocking_notifiers(unsigned long val,
+ struct net_device *dev,
+ struct switchdev_notifier_info *info)
+{
+ return NOTIFY_DONE;
+}
+
static inline bool switchdev_port_same_parent_id(struct net_device *a,
struct net_device *b)
{
diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c
index 74b9d916a58b..e109bb97ce3f 100644
--- a/net/switchdev/switchdev.c
+++ b/net/switchdev/switchdev.c
@@ -535,6 +535,7 @@ int switchdev_port_obj_del(struct net_device *dev,
EXPORT_SYMBOL_GPL(switchdev_port_obj_del);
static ATOMIC_NOTIFIER_HEAD(switchdev_notif_chain);
+static BLOCKING_NOTIFIER_HEAD(switchdev_blocking_notif_chain);
/**
* register_switchdev_notifier - Register notifier
@@ -576,6 +577,31 @@ int call_switchdev_notifiers(unsigned long val, struct net_device *dev,
}
EXPORT_SYMBOL_GPL(call_switchdev_notifiers);
+int register_switchdev_blocking_notifier(struct notifier_block *nb)
+{
+ struct blocking_notifier_head *chain = &switchdev_blocking_notif_chain;
+
+ return blocking_notifier_chain_register(chain, nb);
+}
+EXPORT_SYMBOL_GPL(register_switchdev_blocking_notifier);
+
+int unregister_switchdev_blocking_notifier(struct notifier_block *nb)
+{
+ struct blocking_notifier_head *chain = &switchdev_blocking_notif_chain;
+
+ return blocking_notifier_chain_unregister(chain, nb);
+}
+EXPORT_SYMBOL_GPL(unregister_switchdev_blocking_notifier);
+
+int call_switchdev_blocking_notifiers(unsigned long val, struct net_device *dev,
+ struct switchdev_notifier_info *info)
+{
+ info->dev = dev;
+ return blocking_notifier_call_chain(&switchdev_blocking_notif_chain,
+ val, info);
+}
+EXPORT_SYMBOL_GPL(call_switchdev_blocking_notifiers);
+
bool switchdev_port_same_parent_id(struct net_device *a,
struct net_device *b)
{
--
2.4.11
^ permalink raw reply related
* [PATCH net-next 04/12] rocker: Handle SWITCHDEV_PORT_OBJ_ADD/_DEL
From: Petr Machata @ 2018-11-22 23:28 UTC (permalink / raw)
To: netdev@vger.kernel.org, devel@driverdev.osuosl.org
Cc: Jiri Pirko, Ido Schimmel, davem@davemloft.net,
alexandre.belloni@bootlin.com, ruxandra.radulescu@nxp.com,
ioana.ciornei@nxp.com, gregkh@linuxfoundation.org,
ivecera@redhat.com, andrew@lunn.ch,
vivien.didelot@savoirfairelinux.com, f.fainelli@gmail.com
In-Reply-To: <cover.1542927590.git.petrm@mellanox.com>
Following patches will change the way of distributing port object
changes from a switchdev operation to a switchdev notifier. The
switchdev code currently recursively descends through layers of lower
devices, eventually calling the op on a front-panel port device. The
notifier will instead be sent referencing the bridge port device, which
may be a stacking device that's one of front-panel ports uppers, or a
completely unrelated device.
rocker currently doesn't support any uppers other than bridge. Thus the
only case that a stacked device could be validly referenced by port
object notifications are bridge notifications for VLAN objects added to
the bridge itself. But the driver explicitly rejects such notifications
in rocker_world_port_obj_vlan_add(). It is therefore safe to assume that
the only interesting case is that the notification is on a front-panel
port netdevice.
Subscribe to the blocking notifier chain. In the handler, filter out
notifications on any foreign netdevices. Dispatch the new notifiers to
rocker_port_obj_add() resp. _del() to maintain the behavior that the
switchdev operation based code currently has.
Signed-off-by: Petr Machata <petrm@mellanox.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
---
drivers/net/ethernet/rocker/rocker_main.c | 55 +++++++++++++++++++++++++++++++
1 file changed, 55 insertions(+)
diff --git a/drivers/net/ethernet/rocker/rocker_main.c b/drivers/net/ethernet/rocker/rocker_main.c
index beb06628f22d..806ffe1d906e 100644
--- a/drivers/net/ethernet/rocker/rocker_main.c
+++ b/drivers/net/ethernet/rocker/rocker_main.c
@@ -2812,12 +2812,54 @@ static int rocker_switchdev_event(struct notifier_block *unused,
return NOTIFY_DONE;
}
+static int
+rocker_switchdev_port_obj_event(unsigned long event, struct net_device *netdev,
+ struct switchdev_notifier_port_obj_info *port_obj_info)
+{
+ int err = -EOPNOTSUPP;
+
+ switch (event) {
+ case SWITCHDEV_PORT_OBJ_ADD:
+ err = rocker_port_obj_add(netdev, port_obj_info->obj,
+ port_obj_info->trans);
+ break;
+ case SWITCHDEV_PORT_OBJ_DEL:
+ err = rocker_port_obj_del(netdev, port_obj_info->obj);
+ break;
+ }
+
+ port_obj_info->handled = true;
+ return notifier_from_errno(err);
+}
+
+static int rocker_switchdev_blocking_event(struct notifier_block *unused,
+ unsigned long event, void *ptr)
+{
+ struct net_device *dev = switchdev_notifier_info_to_dev(ptr);
+
+ if (!rocker_port_dev_check(dev))
+ return NOTIFY_DONE;
+
+ switch (event) {
+ case SWITCHDEV_PORT_OBJ_ADD:
+ case SWITCHDEV_PORT_OBJ_DEL:
+ return rocker_switchdev_port_obj_event(event, dev, ptr);
+ }
+
+ return NOTIFY_DONE;
+}
+
static struct notifier_block rocker_switchdev_notifier = {
.notifier_call = rocker_switchdev_event,
};
+static struct notifier_block rocker_switchdev_blocking_notifier = {
+ .notifier_call = rocker_switchdev_blocking_event,
+};
+
static int rocker_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
+ struct notifier_block *nb;
struct rocker *rocker;
int err;
@@ -2933,6 +2975,13 @@ static int rocker_probe(struct pci_dev *pdev, const struct pci_device_id *id)
goto err_register_switchdev_notifier;
}
+ nb = &rocker_switchdev_blocking_notifier;
+ err = register_switchdev_blocking_notifier(nb);
+ if (err) {
+ dev_err(&pdev->dev, "Failed to register switchdev blocking notifier\n");
+ goto err_register_switchdev_blocking_notifier;
+ }
+
rocker->hw.id = rocker_read64(rocker, SWITCH_ID);
dev_info(&pdev->dev, "Rocker switch with id %*phN\n",
@@ -2940,6 +2989,8 @@ static int rocker_probe(struct pci_dev *pdev, const struct pci_device_id *id)
return 0;
+err_register_switchdev_blocking_notifier:
+ unregister_switchdev_notifier(&rocker_switchdev_notifier);
err_register_switchdev_notifier:
unregister_fib_notifier(&rocker->fib_nb);
err_register_fib_notifier:
@@ -2971,6 +3022,10 @@ static int rocker_probe(struct pci_dev *pdev, const struct pci_device_id *id)
static void rocker_remove(struct pci_dev *pdev)
{
struct rocker *rocker = pci_get_drvdata(pdev);
+ struct notifier_block *nb;
+
+ nb = &rocker_switchdev_blocking_notifier;
+ unregister_switchdev_blocking_notifier(nb);
unregister_switchdev_notifier(&rocker_switchdev_notifier);
unregister_fib_notifier(&rocker->fib_nb);
--
2.4.11
^ permalink raw reply related
* [PATCH net-next 03/12] switchdev: Add SWITCHDEV_PORT_OBJ_ADD, SWITCHDEV_PORT_OBJ_DEL
From: Petr Machata @ 2018-11-22 23:28 UTC (permalink / raw)
To: netdev@vger.kernel.org, devel@driverdev.osuosl.org
Cc: Jiri Pirko, Ido Schimmel, davem@davemloft.net,
alexandre.belloni@bootlin.com, ruxandra.radulescu@nxp.com,
ioana.ciornei@nxp.com, gregkh@linuxfoundation.org,
ivecera@redhat.com, andrew@lunn.ch,
vivien.didelot@savoirfairelinux.com, f.fainelli@gmail.com
In-Reply-To: <cover.1542927590.git.petrm@mellanox.com>
An offloading driver may need to have access to switchdev events on
ports that aren't directly under its control. An example is a VXLAN port
attached to a bridge offloaded by a driver. The driver needs to know
about VLANs configured on the VXLAN device. However the VXLAN device
isn't stashed between the bridge and a front-panel-port device (such as
is the case e.g. for LAG devices), so the usual switchdev ops don't
reach the driver.
VXLAN is likely not the only device type like this: in theory any L2
tunnel device that needs offloading will prompt requirement of this
sort. This falsifies the assumption that only the lower devices of a
front panel port need to be notified to achieve flawless offloading.
A way to fix this is to give up the notion of port object addition /
deletion as a switchdev operation, which assumes somewhat tight coupling
between the message producer and consumer. And instead send the message
over a notifier chain.
To that end, introduce two new switchdev notifier types,
SWITCHDEV_PORT_OBJ_ADD and SWITCHDEV_PORT_OBJ_DEL. These notifier types
communicate the same event as the corresponding switchdev op, except in
a form of a notification. struct switchdev_notifier_port_obj_info was
added to carry the fields that the switchdev op carries. An additional
field, handled, will be used to communicate back to switchdev that the
event has reached an interested party, which will be important for the
two-phase commit.
The two switchdev operations themselves are kept in place. Following
patches first convert individual clients to the notifier protocol, and
only then are the operations removed.
Signed-off-by: Petr Machata <petrm@mellanox.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
Reviewed-by: Ido Schimmel <idosch@mellanox.com>
---
include/net/switchdev.h | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/include/net/switchdev.h b/include/net/switchdev.h
index e021b67b9b32..a2f3ebf39301 100644
--- a/include/net/switchdev.h
+++ b/include/net/switchdev.h
@@ -146,6 +146,9 @@ enum switchdev_notifier_type {
SWITCHDEV_FDB_DEL_TO_DEVICE,
SWITCHDEV_FDB_OFFLOADED,
+ SWITCHDEV_PORT_OBJ_ADD, /* Blocking. */
+ SWITCHDEV_PORT_OBJ_DEL, /* Blocking. */
+
SWITCHDEV_VXLAN_FDB_ADD_TO_BRIDGE,
SWITCHDEV_VXLAN_FDB_DEL_TO_BRIDGE,
SWITCHDEV_VXLAN_FDB_ADD_TO_DEVICE,
@@ -165,6 +168,13 @@ struct switchdev_notifier_fdb_info {
offloaded:1;
};
+struct switchdev_notifier_port_obj_info {
+ struct switchdev_notifier_info info; /* must be first */
+ const struct switchdev_obj *obj;
+ struct switchdev_trans *trans;
+ bool handled;
+};
+
static inline struct net_device *
switchdev_notifier_info_to_dev(const struct switchdev_notifier_info *info)
{
--
2.4.11
^ permalink raw reply related
* [PATCH net-next 05/12] net: dsa: slave: Handle SWITCHDEV_PORT_OBJ_ADD/_DEL
From: Petr Machata @ 2018-11-22 23:29 UTC (permalink / raw)
To: netdev@vger.kernel.org, devel@driverdev.osuosl.org
Cc: Jiri Pirko, Ido Schimmel, davem@davemloft.net,
alexandre.belloni@bootlin.com, ruxandra.radulescu@nxp.com,
ioana.ciornei@nxp.com, gregkh@linuxfoundation.org,
ivecera@redhat.com, andrew@lunn.ch,
vivien.didelot@savoirfairelinux.com, f.fainelli@gmail.com
In-Reply-To: <cover.1542927590.git.petrm@mellanox.com>
Following patches will change the way of distributing port object
changes from a switchdev operation to a switchdev notifier. The
switchdev code currently recursively descends through layers of lower
devices, eventually calling the op on a front-panel port device. The
notifier will instead be sent referencing the bridge port device, which
may be a stacking device that's one of front-panel ports uppers, or a
completely unrelated device.
DSA currently doesn't support any other uppers than bridge.
SWITCHDEV_OBJ_ID_HOST_MDB and _PORT_MDB objects are always notified on
the bridge port device. Thus the only case that a stacked device could
be validly referenced by port object notifications are bridge
notifications for VLAN objects added to the bridge itself. But the
driver explicitly rejects such notifications in dsa_port_vlan_add(). It
is therefore safe to assume that the only interesting case is that the
notification is on a front-panel port netdevice. Therefore keep the
filtering by dsa_slave_dev_check() in place.
To handle SWITCHDEV_PORT_OBJ_ADD and _DEL, subscribe to the blocking
notifier chain. Dispatch to rocker_port_obj_add() resp. _del() to
maintain the behavior that the switchdev operation based code currently
has.
Signed-off-by: Petr Machata <petrm@mellanox.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
---
net/dsa/slave.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 56 insertions(+)
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index 7d0c19e7edcf..d00a0b6d4ce0 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -1557,6 +1557,44 @@ static int dsa_slave_switchdev_event(struct notifier_block *unused,
return NOTIFY_BAD;
}
+static int
+dsa_slave_switchdev_port_obj_event(unsigned long event,
+ struct net_device *netdev,
+ struct switchdev_notifier_port_obj_info *port_obj_info)
+{
+ int err = -EOPNOTSUPP;
+
+ switch (event) {
+ case SWITCHDEV_PORT_OBJ_ADD:
+ err = dsa_slave_port_obj_add(netdev, port_obj_info->obj,
+ port_obj_info->trans);
+ break;
+ case SWITCHDEV_PORT_OBJ_DEL:
+ err = dsa_slave_port_obj_del(netdev, port_obj_info->obj);
+ break;
+ }
+
+ port_obj_info->handled = true;
+ return notifier_from_errno(err);
+}
+
+static int dsa_slave_switchdev_blocking_event(struct notifier_block *unused,
+ unsigned long event, void *ptr)
+{
+ struct net_device *dev = switchdev_notifier_info_to_dev(ptr);
+
+ if (!dsa_slave_dev_check(dev))
+ return NOTIFY_DONE;
+
+ switch (event) {
+ case SWITCHDEV_PORT_OBJ_ADD: /* fall through */
+ case SWITCHDEV_PORT_OBJ_DEL:
+ return dsa_slave_switchdev_port_obj_event(event, dev, ptr);
+ }
+
+ return NOTIFY_DONE;
+}
+
static struct notifier_block dsa_slave_nb __read_mostly = {
.notifier_call = dsa_slave_netdevice_event,
};
@@ -1565,8 +1603,13 @@ static struct notifier_block dsa_slave_switchdev_notifier = {
.notifier_call = dsa_slave_switchdev_event,
};
+static struct notifier_block dsa_slave_switchdev_blocking_notifier = {
+ .notifier_call = dsa_slave_switchdev_blocking_event,
+};
+
int dsa_slave_register_notifier(void)
{
+ struct notifier_block *nb;
int err;
err = register_netdevice_notifier(&dsa_slave_nb);
@@ -1577,8 +1620,15 @@ int dsa_slave_register_notifier(void)
if (err)
goto err_switchdev_nb;
+ nb = &dsa_slave_switchdev_blocking_notifier;
+ err = register_switchdev_blocking_notifier(nb);
+ if (err)
+ goto err_switchdev_blocking_nb;
+
return 0;
+err_switchdev_blocking_nb:
+ unregister_switchdev_notifier(&dsa_slave_switchdev_notifier);
err_switchdev_nb:
unregister_netdevice_notifier(&dsa_slave_nb);
return err;
@@ -1586,8 +1636,14 @@ int dsa_slave_register_notifier(void)
void dsa_slave_unregister_notifier(void)
{
+ struct notifier_block *nb;
int err;
+ nb = &dsa_slave_switchdev_blocking_notifier;
+ err = unregister_switchdev_blocking_notifier(nb);
+ if (err)
+ pr_err("DSA: failed to unregister switchdev blocking notifier (%d)\n", err);
+
err = unregister_switchdev_notifier(&dsa_slave_switchdev_notifier);
if (err)
pr_err("DSA: failed to unregister switchdev notifier (%d)\n", err);
--
2.4.11
^ permalink raw reply related
* [PATCH net-next 06/12] staging: fsl-dpaa2: ethsw: Introduce ethsw_port_dev_check()
From: Petr Machata @ 2018-11-22 23:29 UTC (permalink / raw)
To: netdev@vger.kernel.org, devel@driverdev.osuosl.org
Cc: Jiri Pirko, Ido Schimmel, davem@davemloft.net,
alexandre.belloni@bootlin.com, ruxandra.radulescu@nxp.com,
ioana.ciornei@nxp.com, gregkh@linuxfoundation.org,
ivecera@redhat.com, andrew@lunn.ch,
vivien.didelot@savoirfairelinux.com, f.fainelli@gmail.com
In-Reply-To: <cover.1542927590.git.petrm@mellanox.com>
ethsw currently uses an open-coded comparison of netdev_ops to determine
whether whether a device represents a front panel port. Wrap this into a
named function to simplify reuse.
Signed-off-by: Petr Machata <petrm@mellanox.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
---
drivers/staging/fsl-dpaa2/ethsw/ethsw.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
index 7a7ca67822c5..e379b0fa936f 100644
--- a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
+++ b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
@@ -972,6 +972,11 @@ static int port_bridge_leave(struct net_device *netdev)
return err;
}
+static bool ethsw_port_dev_check(const struct net_device *netdev)
+{
+ return netdev->netdev_ops == ðsw_port_ops;
+}
+
static int port_netdevice_event(struct notifier_block *unused,
unsigned long event, void *ptr)
{
@@ -980,7 +985,7 @@ static int port_netdevice_event(struct notifier_block *unused,
struct net_device *upper_dev;
int err = 0;
- if (netdev->netdev_ops != ðsw_port_ops)
+ if (!ethsw_port_dev_check(netdev))
return NOTIFY_DONE;
/* Handle just upper dev link/unlink for the moment */
--
2.4.11
^ permalink raw reply related
* [PATCH net-next 07/12] staging: fsl-dpaa2: ethsw: Handle SWITCHDEV_PORT_OBJ_ADD/_DEL
From: Petr Machata @ 2018-11-22 23:29 UTC (permalink / raw)
To: netdev@vger.kernel.org, devel@driverdev.osuosl.org
Cc: Jiri Pirko, Ido Schimmel, davem@davemloft.net,
alexandre.belloni@bootlin.com, ruxandra.radulescu@nxp.com,
ioana.ciornei@nxp.com, gregkh@linuxfoundation.org,
ivecera@redhat.com, andrew@lunn.ch,
vivien.didelot@savoirfairelinux.com, f.fainelli@gmail.com
In-Reply-To: <cover.1542927590.git.petrm@mellanox.com>
Following patches will change the way of distributing port object
changes from a switchdev operation to a switchdev notifier. The
switchdev code currently recursively descends through layers of lower
devices, eventually calling the op on a front-panel port device. The
notifier will instead be sent referencing the bridge port device, which
may be a stacking device that's one of front-panel ports uppers, or a
completely unrelated device.
ethsw currently doesn't support any uppers other than bridge.
SWITCHDEV_OBJ_ID_HOST_MDB and _PORT_MDB objects are always notified on
the bridge port device. Thus the only case that a stacked device could
be validly referenced by port object notifications are bridge
notifications for VLAN objects added to the bridge itself. But the
driver explicitly rejects such notifications in port_vlans_add(). It is
therefore safe to assume that the only interesting case is that the
notification is on a front-panel port netdevice.
To handle SWITCHDEV_PORT_OBJ_ADD and _DEL, subscribe to the blocking
notifier chain. Dispatch to swdev_port_obj_add() resp. _del() to
maintain the behavior that the switchdev operation based code currently
has.
Signed-off-by: Petr Machata <petrm@mellanox.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
---
drivers/staging/fsl-dpaa2/ethsw/ethsw.c | 56 +++++++++++++++++++++++++++++++++
1 file changed, 56 insertions(+)
diff --git a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
index e379b0fa936f..83e1d92dc7f3 100644
--- a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
+++ b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
@@ -1088,10 +1088,51 @@ static int port_switchdev_event(struct notifier_block *unused,
return NOTIFY_BAD;
}
+static int
+ethsw_switchdev_port_obj_event(unsigned long event, struct net_device *netdev,
+ struct switchdev_notifier_port_obj_info *port_obj_info)
+{
+ int err = -EOPNOTSUPP;
+
+ switch (event) {
+ case SWITCHDEV_PORT_OBJ_ADD:
+ err = swdev_port_obj_add(netdev, port_obj_info->obj,
+ port_obj_info->trans);
+ break;
+ case SWITCHDEV_PORT_OBJ_DEL:
+ err = swdev_port_obj_del(netdev, port_obj_info->obj);
+ break;
+ }
+
+ port_obj_info->handled = true;
+ return notifier_from_errno(err);
+}
+
+static int port_switchdev_blocking_event(struct notifier_block *unused,
+ unsigned long event, void *ptr)
+{
+ struct net_device *dev = switchdev_notifier_info_to_dev(ptr);
+
+ if (!ethsw_port_dev_check(dev))
+ return NOTIFY_DONE;
+
+ switch (event) {
+ case SWITCHDEV_PORT_OBJ_ADD: /* fall through */
+ case SWITCHDEV_PORT_OBJ_DEL:
+ return ethsw_switchdev_port_obj_event(event, dev, ptr);
+ }
+
+ return NOTIFY_DONE;
+}
+
static struct notifier_block port_switchdev_nb = {
.notifier_call = port_switchdev_event,
};
+static struct notifier_block port_switchdev_blocking_nb = {
+ .notifier_call = port_switchdev_blocking_event,
+};
+
static int ethsw_register_notifier(struct device *dev)
{
int err;
@@ -1108,8 +1149,16 @@ static int ethsw_register_notifier(struct device *dev)
goto err_switchdev_nb;
}
+ err = register_switchdev_blocking_notifier(&port_switchdev_blocking_nb);
+ if (err) {
+ dev_err(dev, "Failed to register switchdev blocking notifier\n");
+ goto err_switchdev_blocking_nb;
+ }
+
return 0;
+err_switchdev_blocking_nb:
+ unregister_switchdev_notifier(&port_switchdev_nb);
err_switchdev_nb:
unregister_netdevice_notifier(&port_nb);
return err;
@@ -1296,8 +1345,15 @@ static int ethsw_port_init(struct ethsw_port_priv *port_priv, u16 port)
static void ethsw_unregister_notifier(struct device *dev)
{
+ struct notifier_block *nb;
int err;
+ nb = &port_switchdev_blocking_nb;
+ err = unregister_switchdev_blocking_notifier(nb);
+ if (err)
+ dev_err(dev,
+ "Failed to unregister switchdev blocking notifier (%d)\n", err);
+
err = unregister_switchdev_notifier(&port_switchdev_nb);
if (err)
dev_err(dev,
--
2.4.11
^ permalink raw reply related
* [PATCH net-next 08/12] switchdev: Add helpers to aid traversal through lower devices
From: Petr Machata @ 2018-11-22 23:29 UTC (permalink / raw)
To: netdev@vger.kernel.org, devel@driverdev.osuosl.org
Cc: Jiri Pirko, Ido Schimmel, davem@davemloft.net,
alexandre.belloni@bootlin.com, ruxandra.radulescu@nxp.com,
ioana.ciornei@nxp.com, gregkh@linuxfoundation.org,
ivecera@redhat.com, andrew@lunn.ch,
vivien.didelot@savoirfairelinux.com, f.fainelli@gmail.com
In-Reply-To: <cover.1542927590.git.petrm@mellanox.com>
After the transition from switchdev operations to notifier chain (which
will take place in following patches), the onus is on the driver to find
its own devices below possible layer of LAG or other uppers.
The logic to do so is fairly repetitive: each driver is looking for its
own devices among the lowers of the notified device. For those that it
finds, it calls a handler. To indicate that the event was handled,
struct switchdev_notifier_port_obj_info.handled is set. The differences
lie only in what constitutes an "own" device and what handler to call.
Therefore abstract this logic into two helpers,
switchdev_handle_port_obj_add() and switchdev_handle_port_obj_del(). If
a driver only supports physical ports under a bridge device, it will
simply avoid this layer of indirection.
One area where this helper diverges from the current switchdev behavior
is the case of mixed lowers, some of which are switchdev ports and some
of which are not. Previously, such scenario would fail with -EOPNOTSUPP.
The helper could do that for lowers for which the passed-in predicate
doesn't hold. That would however break the case that switchdev ports
from several different drivers are stashed under one master, a scenario
that switchdev currently happily supports. Therefore tolerate any and
all unknown netdevices, whether they are backed by a switchdev driver
or not.
Signed-off-by: Petr Machata <petrm@mellanox.com>
Reviewed-by: Ido Schimmel <idosch@mellanox.com>
---
include/net/switchdev.h | 33 +++++++++++++++
net/switchdev/switchdev.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 133 insertions(+)
diff --git a/include/net/switchdev.h b/include/net/switchdev.h
index a2f3ebf39301..6dc7de576167 100644
--- a/include/net/switchdev.h
+++ b/include/net/switchdev.h
@@ -210,6 +210,18 @@ void switchdev_port_fwd_mark_set(struct net_device *dev,
bool switchdev_port_same_parent_id(struct net_device *a,
struct net_device *b);
+int switchdev_handle_port_obj_add(struct net_device *dev,
+ struct switchdev_notifier_port_obj_info *port_obj_info,
+ bool (*check_cb)(const struct net_device *dev),
+ int (*add_cb)(struct net_device *dev,
+ const struct switchdev_obj *obj,
+ struct switchdev_trans *trans));
+int switchdev_handle_port_obj_del(struct net_device *dev,
+ struct switchdev_notifier_port_obj_info *port_obj_info,
+ bool (*check_cb)(const struct net_device *dev),
+ int (*del_cb)(struct net_device *dev,
+ const struct switchdev_obj *obj));
+
#define SWITCHDEV_SET_OPS(netdev, ops) ((netdev)->switchdev_ops = (ops))
#else
@@ -284,6 +296,27 @@ static inline bool switchdev_port_same_parent_id(struct net_device *a,
return false;
}
+static inline int
+switchdev_handle_port_obj_add(struct net_device *dev,
+ struct switchdev_notifier_port_obj_info *port_obj_info,
+ bool (*check_cb)(const struct net_device *dev),
+ int (*add_cb)(struct net_device *dev,
+ const struct switchdev_obj *obj,
+ struct switchdev_trans *trans))
+{
+ return 0;
+}
+
+static inline int
+switchdev_handle_port_obj_del(struct net_device *dev,
+ struct switchdev_notifier_port_obj_info *port_obj_info,
+ bool (*check_cb)(const struct net_device *dev),
+ int (*del_cb)(struct net_device *dev,
+ const struct switchdev_obj *obj))
+{
+ return 0;
+}
+
#define SWITCHDEV_SET_OPS(netdev, ops) do {} while (0)
#endif
diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c
index e109bb97ce3f..099434ec7996 100644
--- a/net/switchdev/switchdev.c
+++ b/net/switchdev/switchdev.c
@@ -621,3 +621,103 @@ bool switchdev_port_same_parent_id(struct net_device *a,
return netdev_phys_item_id_same(&a_attr.u.ppid, &b_attr.u.ppid);
}
EXPORT_SYMBOL_GPL(switchdev_port_same_parent_id);
+
+static int __switchdev_handle_port_obj_add(struct net_device *dev,
+ struct switchdev_notifier_port_obj_info *port_obj_info,
+ bool (*check_cb)(const struct net_device *dev),
+ int (*add_cb)(struct net_device *dev,
+ const struct switchdev_obj *obj,
+ struct switchdev_trans *trans))
+{
+ struct net_device *lower_dev;
+ struct list_head *iter;
+ int err = -EOPNOTSUPP;
+
+ if (check_cb(dev)) {
+ /* This flag is only checked if the return value is success. */
+ port_obj_info->handled = true;
+ return add_cb(dev, port_obj_info->obj, port_obj_info->trans);
+ }
+
+ /* Switch ports might be stacked under e.g. a LAG. Ignore the
+ * unsupported devices, another driver might be able to handle them. But
+ * propagate to the callers any hard errors.
+ *
+ * If the driver does its own bookkeeping of stacked ports, it's not
+ * necessary to go through this helper.
+ */
+ netdev_for_each_lower_dev(dev, lower_dev, iter) {
+ err = __switchdev_handle_port_obj_add(lower_dev, port_obj_info,
+ check_cb, add_cb);
+ if (err && err != -EOPNOTSUPP)
+ return err;
+ }
+
+ return err;
+}
+
+int switchdev_handle_port_obj_add(struct net_device *dev,
+ struct switchdev_notifier_port_obj_info *port_obj_info,
+ bool (*check_cb)(const struct net_device *dev),
+ int (*add_cb)(struct net_device *dev,
+ const struct switchdev_obj *obj,
+ struct switchdev_trans *trans))
+{
+ int err;
+
+ err = __switchdev_handle_port_obj_add(dev, port_obj_info, check_cb,
+ add_cb);
+ if (err == -EOPNOTSUPP)
+ err = 0;
+ return err;
+}
+EXPORT_SYMBOL_GPL(switchdev_handle_port_obj_add);
+
+static int __switchdev_handle_port_obj_del(struct net_device *dev,
+ struct switchdev_notifier_port_obj_info *port_obj_info,
+ bool (*check_cb)(const struct net_device *dev),
+ int (*del_cb)(struct net_device *dev,
+ const struct switchdev_obj *obj))
+{
+ struct net_device *lower_dev;
+ struct list_head *iter;
+ int err = -EOPNOTSUPP;
+
+ if (check_cb(dev)) {
+ /* This flag is only checked if the return value is success. */
+ port_obj_info->handled = true;
+ return del_cb(dev, port_obj_info->obj);
+ }
+
+ /* Switch ports might be stacked under e.g. a LAG. Ignore the
+ * unsupported devices, another driver might be able to handle them. But
+ * propagate to the callers any hard errors.
+ *
+ * If the driver does its own bookkeeping of stacked ports, it's not
+ * necessary to go through this helper.
+ */
+ netdev_for_each_lower_dev(dev, lower_dev, iter) {
+ err = __switchdev_handle_port_obj_del(lower_dev, port_obj_info,
+ check_cb, del_cb);
+ if (err && err != -EOPNOTSUPP)
+ return err;
+ }
+
+ return err;
+}
+
+int switchdev_handle_port_obj_del(struct net_device *dev,
+ struct switchdev_notifier_port_obj_info *port_obj_info,
+ bool (*check_cb)(const struct net_device *dev),
+ int (*del_cb)(struct net_device *dev,
+ const struct switchdev_obj *obj))
+{
+ int err;
+
+ err = __switchdev_handle_port_obj_del(dev, port_obj_info, check_cb,
+ del_cb);
+ if (err == -EOPNOTSUPP)
+ err = 0;
+ return err;
+}
+EXPORT_SYMBOL_GPL(switchdev_handle_port_obj_del);
--
2.4.11
^ permalink raw reply related
* [PATCH net-next 09/12] mlxsw: spectrum_switchdev: Handle SWITCHDEV_PORT_OBJ_ADD/_DEL
From: Petr Machata @ 2018-11-22 23:29 UTC (permalink / raw)
To: netdev@vger.kernel.org, devel@driverdev.osuosl.org
Cc: Jiri Pirko, Ido Schimmel, davem@davemloft.net,
alexandre.belloni@bootlin.com, ruxandra.radulescu@nxp.com,
ioana.ciornei@nxp.com, gregkh@linuxfoundation.org,
ivecera@redhat.com, andrew@lunn.ch,
vivien.didelot@savoirfairelinux.com, f.fainelli@gmail.com
In-Reply-To: <cover.1542927590.git.petrm@mellanox.com>
Following patches will change the way of distributing port object
changes from a switchdev operation to a switchdev notifier. The
switchdev code currently recursively descends through layers of lower
devices, eventually calling the op on a front-panel port device. The
notifier will instead be sent referencing the bridge port device, which
may be a stacking device that's one of front-panel ports uppers, or a
completely unrelated device.
To handle SWITCHDEV_PORT_OBJ_ADD and _DEL, subscribe to the blocking
notifier chain. Dispatch to mlxsw_sp_port_obj_add() resp. _del() to
maintain the behavior that the switchdev operation based code currently
has. Defer to switchdev_handle_port_obj_add() / _del() to handle the
recursive descend, because mlxsw supports a number of upper types.
Signed-off-by: Petr Machata <petrm@mellanox.com>
Reviewed-by: Ido Schimmel <idosch@mellanox.com>
---
.../ethernet/mellanox/mlxsw/spectrum_switchdev.c | 45 +++++++++++++++++++++-
1 file changed, 44 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
index b32a5ee57fb9..3756aaecd39c 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
@@ -3118,6 +3118,32 @@ static struct notifier_block mlxsw_sp_switchdev_notifier = {
.notifier_call = mlxsw_sp_switchdev_event,
};
+static int mlxsw_sp_switchdev_blocking_event(struct notifier_block *unused,
+ unsigned long event, void *ptr)
+{
+ struct net_device *dev = switchdev_notifier_info_to_dev(ptr);
+ int err;
+
+ switch (event) {
+ case SWITCHDEV_PORT_OBJ_ADD:
+ err = switchdev_handle_port_obj_add(dev, ptr,
+ mlxsw_sp_port_dev_check,
+ mlxsw_sp_port_obj_add);
+ return notifier_from_errno(err);
+ case SWITCHDEV_PORT_OBJ_DEL:
+ err = switchdev_handle_port_obj_del(dev, ptr,
+ mlxsw_sp_port_dev_check,
+ mlxsw_sp_port_obj_del);
+ return notifier_from_errno(err);
+ }
+
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block mlxsw_sp_switchdev_blocking_notifier = {
+ .notifier_call = mlxsw_sp_switchdev_blocking_event,
+};
+
u8
mlxsw_sp_bridge_port_stp_state(struct mlxsw_sp_bridge_port *bridge_port)
{
@@ -3127,6 +3153,7 @@ mlxsw_sp_bridge_port_stp_state(struct mlxsw_sp_bridge_port *bridge_port)
static int mlxsw_sp_fdb_init(struct mlxsw_sp *mlxsw_sp)
{
struct mlxsw_sp_bridge *bridge = mlxsw_sp->bridge;
+ struct notifier_block *nb;
int err;
err = mlxsw_sp_ageing_set(mlxsw_sp, MLXSW_SP_DEFAULT_AGEING_TIME);
@@ -3141,17 +3168,33 @@ static int mlxsw_sp_fdb_init(struct mlxsw_sp *mlxsw_sp)
return err;
}
+ nb = &mlxsw_sp_switchdev_blocking_notifier;
+ err = register_switchdev_blocking_notifier(nb);
+ if (err) {
+ dev_err(mlxsw_sp->bus_info->dev, "Failed to register switchdev blocking notifier\n");
+ goto err_register_switchdev_blocking_notifier;
+ }
+
INIT_DELAYED_WORK(&bridge->fdb_notify.dw, mlxsw_sp_fdb_notify_work);
bridge->fdb_notify.interval = MLXSW_SP_DEFAULT_LEARNING_INTERVAL;
mlxsw_sp_fdb_notify_work_schedule(mlxsw_sp);
return 0;
+
+err_register_switchdev_blocking_notifier:
+ unregister_switchdev_notifier(&mlxsw_sp_switchdev_notifier);
+ return err;
}
static void mlxsw_sp_fdb_fini(struct mlxsw_sp *mlxsw_sp)
{
+ struct notifier_block *nb;
+
cancel_delayed_work_sync(&mlxsw_sp->bridge->fdb_notify.dw);
- unregister_switchdev_notifier(&mlxsw_sp_switchdev_notifier);
+ nb = &mlxsw_sp_switchdev_blocking_notifier;
+ unregister_switchdev_blocking_notifier(nb);
+
+ unregister_switchdev_notifier(&mlxsw_sp_switchdev_notifier);
}
int mlxsw_sp_switchdev_init(struct mlxsw_sp *mlxsw_sp)
--
2.4.11
^ permalink raw reply related
* [PATCH net-next 10/12] ocelot: Handle SWITCHDEV_PORT_OBJ_ADD/_DEL
From: Petr Machata @ 2018-11-22 23:30 UTC (permalink / raw)
To: netdev@vger.kernel.org, devel@driverdev.osuosl.org
Cc: Jiri Pirko, Ido Schimmel, davem@davemloft.net,
alexandre.belloni@bootlin.com, ruxandra.radulescu@nxp.com,
ioana.ciornei@nxp.com, gregkh@linuxfoundation.org,
ivecera@redhat.com, andrew@lunn.ch,
vivien.didelot@savoirfairelinux.com, f.fainelli@gmail.com
In-Reply-To: <cover.1542927590.git.petrm@mellanox.com>
Following patches will change the way of distributing port object
changes from a switchdev operation to a switchdev notifier. The
switchdev code currently recursively descends through layers of lower
devices, eventually calling the op on a front-panel port device. The
notifier will instead be sent referencing the bridge port device, which
may be a stacking device that's one of front-panel ports uppers, or a
completely unrelated device.
Dispatch the new events to ocelot_port_obj_add() resp. _del() to
maintain the same behavior that the switchdev operation based code
currently has. Pass through switchdev_handle_port_obj_add() / _del() to
handle the recursive descend, because Ocelot supports LAG uppers.
Register to the new switchdev blocking notifier chain to get the new
events when they start getting distributed.
Signed-off-by: Petr Machata <petrm@mellanox.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
---
drivers/net/ethernet/mscc/ocelot.c | 28 ++++++++++++++++++++++++++++
drivers/net/ethernet/mscc/ocelot.h | 1 +
drivers/net/ethernet/mscc/ocelot_board.c | 3 +++
3 files changed, 32 insertions(+)
diff --git a/drivers/net/ethernet/mscc/ocelot.c b/drivers/net/ethernet/mscc/ocelot.c
index 3238b9ee42f3..01403b530522 100644
--- a/drivers/net/ethernet/mscc/ocelot.c
+++ b/drivers/net/ethernet/mscc/ocelot.c
@@ -1595,6 +1595,34 @@ struct notifier_block ocelot_netdevice_nb __read_mostly = {
};
EXPORT_SYMBOL(ocelot_netdevice_nb);
+static int ocelot_switchdev_blocking_event(struct notifier_block *unused,
+ unsigned long event, void *ptr)
+{
+ struct net_device *dev = switchdev_notifier_info_to_dev(ptr);
+ int err;
+
+ switch (event) {
+ /* Blocking events. */
+ case SWITCHDEV_PORT_OBJ_ADD:
+ err = switchdev_handle_port_obj_add(dev, ptr,
+ ocelot_netdevice_dev_check,
+ ocelot_port_obj_add);
+ return notifier_from_errno(err);
+ case SWITCHDEV_PORT_OBJ_DEL:
+ err = switchdev_handle_port_obj_del(dev, ptr,
+ ocelot_netdevice_dev_check,
+ ocelot_port_obj_del);
+ return notifier_from_errno(err);
+ }
+
+ return NOTIFY_DONE;
+}
+
+struct notifier_block ocelot_switchdev_blocking_nb __read_mostly = {
+ .notifier_call = ocelot_switchdev_blocking_event,
+};
+EXPORT_SYMBOL(ocelot_switchdev_blocking_nb);
+
int ocelot_probe_port(struct ocelot *ocelot, u8 port,
void __iomem *regs,
struct phy_device *phy)
diff --git a/drivers/net/ethernet/mscc/ocelot.h b/drivers/net/ethernet/mscc/ocelot.h
index 62c7c8eb00d9..086775f7b52f 100644
--- a/drivers/net/ethernet/mscc/ocelot.h
+++ b/drivers/net/ethernet/mscc/ocelot.h
@@ -499,5 +499,6 @@ int ocelot_probe_port(struct ocelot *ocelot, u8 port,
struct phy_device *phy);
extern struct notifier_block ocelot_netdevice_nb;
+extern struct notifier_block ocelot_switchdev_blocking_nb;
#endif
diff --git a/drivers/net/ethernet/mscc/ocelot_board.c b/drivers/net/ethernet/mscc/ocelot_board.c
index 4c23d18bbf44..ca3ea2fbfcd0 100644
--- a/drivers/net/ethernet/mscc/ocelot_board.c
+++ b/drivers/net/ethernet/mscc/ocelot_board.c
@@ -12,6 +12,7 @@
#include <linux/of_platform.h>
#include <linux/mfd/syscon.h>
#include <linux/skbuff.h>
+#include <net/switchdev.h>
#include "ocelot.h"
@@ -328,6 +329,7 @@ static int mscc_ocelot_probe(struct platform_device *pdev)
}
register_netdevice_notifier(&ocelot_netdevice_nb);
+ register_switchdev_blocking_notifier(&ocelot_switchdev_blocking_nb);
dev_info(&pdev->dev, "Ocelot switch probed\n");
@@ -342,6 +344,7 @@ static int mscc_ocelot_remove(struct platform_device *pdev)
struct ocelot *ocelot = platform_get_drvdata(pdev);
ocelot_deinit(ocelot);
+ unregister_switchdev_blocking_notifier(&ocelot_switchdev_blocking_nb);
unregister_netdevice_notifier(&ocelot_netdevice_nb);
return 0;
--
2.4.11
^ permalink raw reply related
* [PATCH net-next 11/12] switchdev: Replace port obj add/del SDO with a notification
From: Petr Machata @ 2018-11-22 23:32 UTC (permalink / raw)
To: netdev@vger.kernel.org, devel@driverdev.osuosl.org
Cc: Jiri Pirko, Ido Schimmel, davem@davemloft.net,
alexandre.belloni@bootlin.com, ruxandra.radulescu@nxp.com,
ioana.ciornei@nxp.com, gregkh@linuxfoundation.org,
ivecera@redhat.com, andrew@lunn.ch,
vivien.didelot@savoirfairelinux.com, f.fainelli@gmail.com
In-Reply-To: <cover.1542927590.git.petrm@mellanox.com>
Drop switchdev_ops.switchdev_port_obj_add and _del. Drop the uses of
this field from all clients, which were migrated to use switchdev
notification in the previous patches.
Add a new function switchdev_port_obj_notify() that sends the switchdev
notifications SWITCHDEV_PORT_OBJ_ADD and _DEL.
Update switchdev_port_obj_del_now() to dispatch to this new function.
Drop __switchdev_port_obj_add() and update switchdev_port_obj_add()
likewise.
Signed-off-by: Petr Machata <petrm@mellanox.com>
Reviewed-by: Ido Schimmel <idosch@mellanox.com>
---
.../ethernet/mellanox/mlxsw/spectrum_switchdev.c | 2 -
drivers/net/ethernet/mscc/ocelot.c | 2 -
drivers/net/ethernet/rocker/rocker_main.c | 2 -
drivers/staging/fsl-dpaa2/ethsw/ethsw.c | 2 -
include/net/switchdev.h | 9 ---
net/dsa/slave.c | 2 -
net/switchdev/switchdev.c | 67 ++++++++--------------
7 files changed, 25 insertions(+), 61 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
index 3756aaecd39c..73e5db176d7e 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
@@ -1968,8 +1968,6 @@ static struct mlxsw_sp_port *mlxsw_sp_lag_rep_port(struct mlxsw_sp *mlxsw_sp,
static const struct switchdev_ops mlxsw_sp_port_switchdev_ops = {
.switchdev_port_attr_get = mlxsw_sp_port_attr_get,
.switchdev_port_attr_set = mlxsw_sp_port_attr_set,
- .switchdev_port_obj_add = mlxsw_sp_port_obj_add,
- .switchdev_port_obj_del = mlxsw_sp_port_obj_del,
};
static int
diff --git a/drivers/net/ethernet/mscc/ocelot.c b/drivers/net/ethernet/mscc/ocelot.c
index 01403b530522..7f8da8873a96 100644
--- a/drivers/net/ethernet/mscc/ocelot.c
+++ b/drivers/net/ethernet/mscc/ocelot.c
@@ -1337,8 +1337,6 @@ static int ocelot_port_obj_del(struct net_device *dev,
static const struct switchdev_ops ocelot_port_switchdev_ops = {
.switchdev_port_attr_get = ocelot_port_attr_get,
.switchdev_port_attr_set = ocelot_port_attr_set,
- .switchdev_port_obj_add = ocelot_port_obj_add,
- .switchdev_port_obj_del = ocelot_port_obj_del,
};
static int ocelot_port_bridge_join(struct ocelot_port *ocelot_port,
diff --git a/drivers/net/ethernet/rocker/rocker_main.c b/drivers/net/ethernet/rocker/rocker_main.c
index 806ffe1d906e..f05d5c1341b6 100644
--- a/drivers/net/ethernet/rocker/rocker_main.c
+++ b/drivers/net/ethernet/rocker/rocker_main.c
@@ -2145,8 +2145,6 @@ static int rocker_port_obj_del(struct net_device *dev,
static const struct switchdev_ops rocker_port_switchdev_ops = {
.switchdev_port_attr_get = rocker_port_attr_get,
.switchdev_port_attr_set = rocker_port_attr_set,
- .switchdev_port_obj_add = rocker_port_obj_add,
- .switchdev_port_obj_del = rocker_port_obj_del,
};
struct rocker_fib_event_work {
diff --git a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
index 83e1d92dc7f3..06a233c7cdd3 100644
--- a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
+++ b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
@@ -930,8 +930,6 @@ static int swdev_port_obj_del(struct net_device *netdev,
static const struct switchdev_ops ethsw_port_switchdev_ops = {
.switchdev_port_attr_get = swdev_port_attr_get,
.switchdev_port_attr_set = swdev_port_attr_set,
- .switchdev_port_obj_add = swdev_port_obj_add,
- .switchdev_port_obj_del = swdev_port_obj_del,
};
/* For the moment, only flood setting needs to be updated */
diff --git a/include/net/switchdev.h b/include/net/switchdev.h
index 6dc7de576167..866b6d148b77 100644
--- a/include/net/switchdev.h
+++ b/include/net/switchdev.h
@@ -121,10 +121,6 @@ typedef int switchdev_obj_dump_cb_t(struct switchdev_obj *obj);
* @switchdev_port_attr_get: Get a port attribute (see switchdev_attr).
*
* @switchdev_port_attr_set: Set a port attribute (see switchdev_attr).
- *
- * @switchdev_port_obj_add: Add an object to port (see switchdev_obj_*).
- *
- * @switchdev_port_obj_del: Delete an object from port (see switchdev_obj_*).
*/
struct switchdev_ops {
int (*switchdev_port_attr_get)(struct net_device *dev,
@@ -132,11 +128,6 @@ struct switchdev_ops {
int (*switchdev_port_attr_set)(struct net_device *dev,
const struct switchdev_attr *attr,
struct switchdev_trans *trans);
- int (*switchdev_port_obj_add)(struct net_device *dev,
- const struct switchdev_obj *obj,
- struct switchdev_trans *trans);
- int (*switchdev_port_obj_del)(struct net_device *dev,
- const struct switchdev_obj *obj);
};
enum switchdev_notifier_type {
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index d00a0b6d4ce0..268119cf7117 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -1050,8 +1050,6 @@ static const struct net_device_ops dsa_slave_netdev_ops = {
static const struct switchdev_ops dsa_slave_switchdev_ops = {
.switchdev_port_attr_get = dsa_slave_port_attr_get,
.switchdev_port_attr_set = dsa_slave_port_attr_set,
- .switchdev_port_obj_add = dsa_slave_port_obj_add,
- .switchdev_port_obj_del = dsa_slave_port_obj_del,
};
static struct device_type dsa_type = {
diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c
index 099434ec7996..fe23fac4dc4b 100644
--- a/net/switchdev/switchdev.c
+++ b/net/switchdev/switchdev.c
@@ -353,30 +353,29 @@ static size_t switchdev_obj_size(const struct switchdev_obj *obj)
return 0;
}
-static int __switchdev_port_obj_add(struct net_device *dev,
- const struct switchdev_obj *obj,
- struct switchdev_trans *trans)
+static int switchdev_port_obj_notify(enum switchdev_notifier_type nt,
+ struct net_device *dev,
+ const struct switchdev_obj *obj,
+ struct switchdev_trans *trans)
{
- const struct switchdev_ops *ops = dev->switchdev_ops;
- struct net_device *lower_dev;
- struct list_head *iter;
- int err = -EOPNOTSUPP;
-
- if (ops && ops->switchdev_port_obj_add)
- return ops->switchdev_port_obj_add(dev, obj, trans);
+ int rc;
+ int err;
- /* Switch device port(s) may be stacked under
- * bond/team/vlan dev, so recurse down to add object on
- * each port.
- */
+ struct switchdev_notifier_port_obj_info obj_info = {
+ .obj = obj,
+ .trans = trans,
+ .handled = false,
+ };
- netdev_for_each_lower_dev(dev, lower_dev, iter) {
- err = __switchdev_port_obj_add(lower_dev, obj, trans);
- if (err)
- break;
+ rc = call_switchdev_blocking_notifiers(nt, dev, &obj_info.info);
+ err = notifier_to_errno(rc);
+ if (err) {
+ WARN_ON(!obj_info.handled);
+ return err;
}
-
- return err;
+ if (!obj_info.handled)
+ return -EOPNOTSUPP;
+ return 0;
}
static int switchdev_port_obj_add_now(struct net_device *dev,
@@ -397,7 +396,8 @@ static int switchdev_port_obj_add_now(struct net_device *dev,
*/
trans.ph_prepare = true;
- err = __switchdev_port_obj_add(dev, obj, &trans);
+ err = switchdev_port_obj_notify(SWITCHDEV_PORT_OBJ_ADD,
+ dev, obj, &trans);
if (err) {
/* Prepare phase failed: abort the transaction. Any
* resources reserved in the prepare phase are
@@ -416,7 +416,8 @@ static int switchdev_port_obj_add_now(struct net_device *dev,
*/
trans.ph_prepare = false;
- err = __switchdev_port_obj_add(dev, obj, &trans);
+ err = switchdev_port_obj_notify(SWITCHDEV_PORT_OBJ_ADD,
+ dev, obj, &trans);
WARN(err, "%s: Commit of object (id=%d) failed.\n", dev->name, obj->id);
switchdev_trans_items_warn_destroy(dev, &trans);
@@ -471,26 +472,8 @@ EXPORT_SYMBOL_GPL(switchdev_port_obj_add);
static int switchdev_port_obj_del_now(struct net_device *dev,
const struct switchdev_obj *obj)
{
- const struct switchdev_ops *ops = dev->switchdev_ops;
- struct net_device *lower_dev;
- struct list_head *iter;
- int err = -EOPNOTSUPP;
-
- if (ops && ops->switchdev_port_obj_del)
- return ops->switchdev_port_obj_del(dev, obj);
-
- /* Switch device port(s) may be stacked under
- * bond/team/vlan dev, so recurse down to delete object on
- * each port.
- */
-
- netdev_for_each_lower_dev(dev, lower_dev, iter) {
- err = switchdev_port_obj_del_now(lower_dev, obj);
- if (err)
- break;
- }
-
- return err;
+ return switchdev_port_obj_notify(SWITCHDEV_PORT_OBJ_DEL,
+ dev, obj, NULL);
}
static void switchdev_port_obj_del_deferred(struct net_device *dev,
--
2.4.11
^ permalink raw reply related
* [PATCH net-next 12/12] rocker, dsa, ethsw: Don't filter VLAN events on bridge itself
From: Petr Machata @ 2018-11-22 23:48 UTC (permalink / raw)
To: netdev@vger.kernel.org, devel@driverdev.osuosl.org
Cc: Jiri Pirko, Ido Schimmel, davem@davemloft.net,
alexandre.belloni@bootlin.com, ruxandra.radulescu@nxp.com,
ioana.ciornei@nxp.com, gregkh@linuxfoundation.org,
ivecera@redhat.com, andrew@lunn.ch,
vivien.didelot@savoirfairelinux.com, f.fainelli@gmail.com
In-Reply-To: <cover.1542927590.git.petrm@mellanox.com>
Due to an explicit check in rocker_world_port_obj_vlan_add(),
dsa_slave_switchdev_event() resp. port_switchdev_event(), VLAN objects
that are added to a device that is not a front-panel port device are
ignored. Therefore this check is immaterial.
Signed-off-by: Petr Machata <petrm@mellanox.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
---
drivers/net/ethernet/rocker/rocker_main.c | 3 ---
drivers/staging/fsl-dpaa2/ethsw/ethsw.c | 3 ---
net/dsa/port.c | 3 ---
3 files changed, 9 deletions(-)
diff --git a/drivers/net/ethernet/rocker/rocker_main.c b/drivers/net/ethernet/rocker/rocker_main.c
index f05d5c1341b6..6213827e3956 100644
--- a/drivers/net/ethernet/rocker/rocker_main.c
+++ b/drivers/net/ethernet/rocker/rocker_main.c
@@ -1632,9 +1632,6 @@ rocker_world_port_obj_vlan_add(struct rocker_port *rocker_port,
{
struct rocker_world_ops *wops = rocker_port->rocker->wops;
- if (netif_is_bridge_master(vlan->obj.orig_dev))
- return -EOPNOTSUPP;
-
if (!wops->port_obj_vlan_add)
return -EOPNOTSUPP;
diff --git a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
index 06a233c7cdd3..4fa37d6e598b 100644
--- a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
+++ b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
@@ -719,9 +719,6 @@ static int port_vlans_add(struct net_device *netdev,
struct ethsw_port_priv *port_priv = netdev_priv(netdev);
int vid, err = 0;
- if (netif_is_bridge_master(vlan->obj.orig_dev))
- return -EOPNOTSUPP;
-
if (switchdev_trans_ph_prepare(trans))
return 0;
diff --git a/net/dsa/port.c b/net/dsa/port.c
index ed0595459df1..2d7e01b23572 100644
--- a/net/dsa/port.c
+++ b/net/dsa/port.c
@@ -252,9 +252,6 @@ int dsa_port_vlan_add(struct dsa_port *dp,
.vlan = vlan,
};
- if (netif_is_bridge_master(vlan->obj.orig_dev))
- return -EOPNOTSUPP;
-
if (br_vlan_enabled(dp->bridge_dev))
return dsa_port_notify(dp, DSA_NOTIFIER_VLAN_ADD, &info);
--
2.4.11
^ permalink raw reply related
* Re: [PATCH v2 bpf-next] bpf: add skb->tstamp r/w access from tc clsact and cg skb progs
From: Alexei Starovoitov @ 2018-11-22 23:49 UTC (permalink / raw)
To: Vlad Dumitrescu
Cc: Alexei Starovoitov, Daniel Borkmann, netdev, Eric Dumazet,
Willem de Bruijn
In-Reply-To: <20181122193916.242369-1-vladum@google.com>
On Thu, Nov 22, 2018 at 02:39:16PM -0500, Vlad Dumitrescu wrote:
> This could be used to rate limit egress traffic in concert with a qdisc
> which supports Earliest Departure Time, such as FQ.
>
> Write access from cg skb progs only with CAP_SYS_ADMIN, since the value
> will be used by downstream qdiscs. It might make sense to relax this.
>
> Changes v1 -> v2:
> - allow access from cg skb, write only with CAP_SYS_ADMIN
>
> Signed-off-by: Vlad Dumitrescu <vladum@google.com>
Applied to bpf-next.
I copied Eric's and Willem's Acks from v1, since v2 is essentially the same.
Thanks everyone!
^ permalink raw reply
* RE: [PATCH net-next v2 1/4] enetc: Introduce basic PF and VF ENETC ethernet drivers
From: Claudiu Manoil @ 2018-11-23 10:35 UTC (permalink / raw)
To: Andrew Lunn
Cc: David Miller, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org, Alexandru Marginean,
Catalin Horghidan
In-Reply-To: <20181122180557.GC10697@lunn.ch>
>-----Original Message-----
>From: Andrew Lunn <andrew@lunn.ch>
>Sent: Thursday, November 22, 2018 8:06 PM
>To: Claudiu Manoil <claudiu.manoil@nxp.com>
>Cc: David Miller <davem@davemloft.net>; netdev@vger.kernel.org; linux-
>kernel@vger.kernel.org; Alexandru Marginean
><alexandru.marginean@nxp.com>; Catalin Horghidan
><catalin.horghidan@nxp.com>
>Subject: Re: [PATCH net-next v2 1/4] enetc: Introduce basic PF and VF ENETC
>ethernet drivers
>
>On Thu, Nov 22, 2018 at 01:06:01PM +0000, Claudiu Manoil wrote:
>> >-----Original Message-----
>> >From: David Miller <davem@davemloft.net>
>> >Sent: Thursday, November 22, 2018 2:21 AM
>> >To: Claudiu Manoil <claudiu.manoil@nxp.com>
>> >Cc: netdev@vger.kernel.org; linux-kernel@vger.kernel.org; Alexandru
>> >Marginean <alexandru.marginean@nxp.com>; Catalin Horghidan
>> ><catalin.horghidan@nxp.com>
>> >Subject: Re: [PATCH net-next v2 1/4] enetc: Introduce basic PF and VF ENETC
>> >ethernet drivers
>> >
>> >From: Claudiu Manoil <claudiu.manoil@nxp.com>
>> >Date: Tue, 20 Nov 2018 20:15:31 +0200
>> >
>> >> diff --git a/drivers/net/ethernet/freescale/Makefile
>> >b/drivers/net/ethernet/freescale/Makefile
>> >> index 3b4ff08..20e5c2f9 100644
>> >> --- a/drivers/net/ethernet/freescale/Makefile
>> >> +++ b/drivers/net/ethernet/freescale/Makefile
>> >> @@ -23,3 +23,4 @@ obj-$(CONFIG_FSL_FMAN) += fman/
>> >> obj-$(CONFIG_FSL_DPAA_ETH) += dpaa/
>> >>
>> >> obj-$(CONFIG_FSL_DPAA2_ETH) += dpaa2/
>> >> +obj-$(CONFIG_NET_VENDOR_FREESCALE) += enetc/
>> >
>> >The driver enable Kconfig option should guard traversing into the
>> >driver subdirectory, not the vendor enable Kconfig knob.
>>
>> The enetc/ dir contains 2 drivers, that share a lot of common code.
>> Would you agree if I change the vendor enable with the two configs
>> (one for each driver) as below?
>>
>> -obj-$(CONFIG_NET_VENDOR_FREESCALE) += enetc/
>> +obj-$(CONFIG_FSL_ENETC) += enetc/
>> +obj-$(CONFIG_FSL_ENETC_VF) += enetc/
>
>CONFIG_NET_VENDOR_FREESCALE should hide/show all Freescale drivers.
>
>Once you show all Freescale drivers, there should be an option to
>enable each individual driver.
>
>Does the ENETC_VF driver depend on the ENETC driver? If so, when
>CONFIG_FSL_ENETC is enabled, the CONFIG_FSL_ENETC_VF should be
>unhidden.
>
The two drivers are independent as can be seen from enetc/Makefile.
E.g., in a virtualized env you can have a linux instance (guest) containing
only the VF driver.
Sending v3 with the above mentioned change.
^ permalink raw reply
* Re: [PATCH] mm: Replace all open encodings for NUMA_NO_NODE
From: David Hildenbrand @ 2018-11-23 10:36 UTC (permalink / raw)
To: Anshuman Khandual, linux-mm, linux-kernel
Cc: ocfs2-devel, linux-fbdev, dri-devel, netdev, intel-wired-lan,
linux-media, iommu, linux-rdma, dmaengine, linux-block,
sparclinux, linuxppc-dev, linux-ia64, linux-alpha, akpm,
jiangqi903, hverkuil
In-Reply-To: <1542966856-12619-1-git-send-email-anshuman.khandual@arm.com>
On 23.11.18 10:54, Anshuman Khandual wrote:
> At present there are multiple places where invalid node number is encoded
> as -1. Even though implicitly understood it is always better to have macros
> in there. Replace these open encodings for an invalid node number with the
> global macro NUMA_NO_NODE. This helps remove NUMA related assumptions like
> 'invalid node' from various places redirecting them to a common definition.
>
> Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
> ---
>
> Changes in V1:
>
> - Dropped OCFS2 changes per Joseph
> - Dropped media/video drivers changes per Hans
>
> RFC - https://patchwork.kernel.org/patch/10678035/
>
> Build tested this with multiple cross compiler options like alpha, sparc,
> arm64, x86, powerpc, powerpc64le etc with their default config which might
> not have compiled tested all driver related changes. I will appreciate
> folks giving this a test in their respective build environment.
>
> All these places for replacement were found by running the following grep
> patterns on the entire kernel code. Please let me know if this might have
> missed some instances. This might also have replaced some false positives.
> I will appreciate suggestions, inputs and review.
>
> 1. git grep "nid == -1"
> 2. git grep "node == -1"
> 3. git grep "nid = -1"
> 4. git grep "node = -1"
Hopefully you found most users :)
Did you check if some are encoded into function calls? f(-1, ...)
Reviewed-by: David Hildenbrand <david@redhat.com>
--
Thanks,
David / dhildenb
^ permalink raw reply
* [PATCH net-next v3 0/4] Introduce ENETC ethernet drivers
From: Claudiu Manoil @ 2018-11-23 10:45 UTC (permalink / raw)
To: David S . Miller, netdev
Cc: linux-kernel, alexandru.marginean, catalin.horghidan
ENETC is a multi-port virtualized Ethernet controller supporting GbE
designs and Time-Sensitive Networking (TSN) functionality.
ENETC is operating as an SR-IOV multi-PF capable Root Complex Integrated
Endpoint (RCIE). As such, it contains multiple physical (PF) and virtual
(VF) PCIe functions, discoverable by standard PCI Express.
The patch series adds basic enablement for these otherwise standard
buffer descriptor (BD) ring based ethernet devices (PCIe PFs and VFs),
currently included in the 64-bit dual ARMv8 processors LS1028A SoC.
The driver is portable to 32-bit designs, and it's independent of CPU
endianness.
Contributors:
Alex Marginean <alexandru.marginean@nxp.com>
Catalin Horghidan <catalin.horghidan@nxp.com>
TODO list:
* IEEE 1588 PTP support;
* TSN support;
* MDIO support and VF link management;
* power management support;
* flow control support;
* TC offloading with h/w MQPRIO;
* interrupt coalescing, configurable BD ring sizes, and other usual
config options if missing.
Claudiu Manoil (4):
enetc: Introduce basic PF and VF ENETC ethernet drivers
enetc: Add ethtool statistics
enetc: Add vf to pf messaging support
enetc: Add RFS and RSS support
MAINTAINERS | 6 +
drivers/net/ethernet/freescale/Kconfig | 1 +
drivers/net/ethernet/freescale/Makefile | 3 +
drivers/net/ethernet/freescale/enetc/Kconfig | 19 +
drivers/net/ethernet/freescale/enetc/Makefile | 15 +
drivers/net/ethernet/freescale/enetc/enetc.c | 1575 ++++++++++++++++++++
drivers/net/ethernet/freescale/enetc/enetc.h | 229 +++
drivers/net/ethernet/freescale/enetc/enetc_cbdr.c | 210 +++
.../net/ethernet/freescale/enetc/enetc_ethtool.c | 597 ++++++++
drivers/net/ethernet/freescale/enetc/enetc_hw.h | 519 +++++++
drivers/net/ethernet/freescale/enetc/enetc_msg.c | 164 ++
drivers/net/ethernet/freescale/enetc/enetc_pf.c | 921 ++++++++++++
drivers/net/ethernet/freescale/enetc/enetc_pf.h | 49 +
drivers/net/ethernet/freescale/enetc/enetc_vf.c | 255 ++++
14 files changed, 4563 insertions(+)
create mode 100644 drivers/net/ethernet/freescale/enetc/Kconfig
create mode 100644 drivers/net/ethernet/freescale/enetc/Makefile
create mode 100644 drivers/net/ethernet/freescale/enetc/enetc.c
create mode 100644 drivers/net/ethernet/freescale/enetc/enetc.h
create mode 100644 drivers/net/ethernet/freescale/enetc/enetc_cbdr.c
create mode 100644 drivers/net/ethernet/freescale/enetc/enetc_ethtool.c
create mode 100644 drivers/net/ethernet/freescale/enetc/enetc_hw.h
create mode 100644 drivers/net/ethernet/freescale/enetc/enetc_msg.c
create mode 100644 drivers/net/ethernet/freescale/enetc/enetc_pf.c
create mode 100644 drivers/net/ethernet/freescale/enetc/enetc_pf.h
create mode 100644 drivers/net/ethernet/freescale/enetc/enetc_vf.c
--
2.7.4
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox