* [PATCH] sfp: sfp_read: split-up request when hw rx buffer is too small.
From: René van Dorst @ 2019-01-23 21:20 UTC (permalink / raw)
To: Andrew Lunn, Florian Fainelli, Heiner Kallweit, David S. Miller,
netdev
Cc: René van Dorst
Without this patch sfp code retries to read the full struct sfp_eeprom_id
id out of the SFP eeprom. Sizeof(id) is 96 bytes.
My i2c hardware, Mediatek mt7621, has a rx buffer of 64 bytes.
So sfp_read gets -NOSUPPORTED back on his turn return -EAGAIN.
Same issue is with the SFP_EXT_STATUS data which is 92 bytes.
By split-up the request in multiple smaller requests with a max size of i2c
max_read_len, we can readout the SFP module successfully.
Tested with MT7621 and two Fiberstore modules SFP-GB-GE-T and SFP-GE-BX.
Signed-off-by: René van Dorst <opensource@vdorst.com>
---
drivers/net/phy/sfp.c | 23 ++++++++++++++++++++++-
1 file changed, 22 insertions(+), 1 deletion(-)
diff --git a/drivers/net/phy/sfp.c b/drivers/net/phy/sfp.c
index fd8bb998ae52..1352a19571cd 100644
--- a/drivers/net/phy/sfp.c
+++ b/drivers/net/phy/sfp.c
@@ -367,7 +367,28 @@ static void sfp_set_state(struct sfp *sfp, unsigned int state)
static int sfp_read(struct sfp *sfp, bool a2, u8 addr, void *buf, size_t len)
{
- return sfp->read(sfp, a2, addr, buf, len);
+ const struct i2c_adapter_quirks *q = sfp->i2c->quirks;
+ int ret;
+ size_t rx_bytes = 0;
+
+ /* Many i2c hw have limited rx buffers, split-up request when needed. */
+ while ((q->max_read_len) && (len > q->max_read_len)) {
+ ret = sfp->read(sfp, a2, addr, buf, q->max_read_len);
+ if (ret < 0)
+ return ret;
+ rx_bytes += ret;
+ addr += q->max_read_len;
+ buf += q->max_read_len;
+ len -= q->max_read_len;
+ }
+
+ ret = sfp->read(sfp, a2, addr, buf, len);
+ if (ret < 0)
+ return ret;
+
+ rx_bytes += ret;
+
+ return rx_bytes;
}
static int sfp_write(struct sfp *sfp, bool a2, u8 addr, void *buf, size_t len)
--
2.19.1
^ permalink raw reply related
* [PATCH net] rhashtable: avoid reschedule loop after rapid growth and shrink
From: Josh Elsasser @ 2019-01-23 21:17 UTC (permalink / raw)
To: David S . Miller
Cc: josh, Josh Elsasser, Thomas Graf, Herbert Xu, netdev,
linux-kernel
When running workloads with large bursts of fragmented packets, we've seen
a few machines stuck returning -EEXIST from rht_shrink() and endlessly
rescheduling their hash table's deferred work, pegging a CPU core.
Root cause is commit da20420f83ea ("rhashtable: Add nested tables"), which
stops ignoring the return code of rhashtable_shrink() and the reallocs
used to grow the hashtable. This uncovers a bug in the shrink logic where
"needs to shrink" check runs against the last table but the actual shrink
operation runs on the first bucket_table in the hashtable (see below):
+-------+ +--------------+ +---------------+
| ht | | "first" tbl | | "last" tbl |
| - tbl ---> | - future_tbl ---------> | - future_tbl ---> NULL
+-------+ +--------------+ +---------------+
^^^ ^^^
used by rhashtable_shrink() used by rht_shrink_below_30()
A rehash then stalls out when both the last table needs to shrink, the
first table has more elements than the target size, but rht_shrink() hits
a non-NULL future_tbl and returns -EEXIST. This skips the item rehashing
and kicks off a reschedule loop, as no forward progress can be made while
the rhashtable needs to shrink.
Extend rhashtable_shrink() with a "tbl" param to avoid endless exit-and-
reschedules after hitting the EEXIST, allowing it to check a future_tbl
pointer that can actually be non-NULL and make forward progress when the
hashtable needs to shrink.
Fixes: da20420f83ea ("rhashtable: Add nested tables")
Signed-off-by: Josh Elsasser <jelsasser@appneta.com>
---
lib/rhashtable.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/lib/rhashtable.c b/lib/rhashtable.c
index 852ffa5160f1..98e91f9544fa 100644
--- a/lib/rhashtable.c
+++ b/lib/rhashtable.c
@@ -377,9 +377,9 @@ static int rhashtable_rehash_alloc(struct rhashtable *ht,
* It is valid to have concurrent insertions and deletions protected by per
* bucket locks or concurrent RCU protected lookups and traversals.
*/
-static int rhashtable_shrink(struct rhashtable *ht)
+static int rhashtable_shrink(struct rhashtable *ht,
+ struct bucket_table *old_tbl)
{
- struct bucket_table *old_tbl = rht_dereference(ht->tbl, ht);
unsigned int nelems = atomic_read(&ht->nelems);
unsigned int size = 0;
@@ -412,7 +412,7 @@ static void rht_deferred_worker(struct work_struct *work)
if (rht_grow_above_75(ht, tbl))
err = rhashtable_rehash_alloc(ht, tbl, tbl->size * 2);
else if (ht->p.automatic_shrinking && rht_shrink_below_30(ht, tbl))
- err = rhashtable_shrink(ht);
+ err = rhashtable_shrink(ht, tbl);
else if (tbl->nest)
err = rhashtable_rehash_alloc(ht, tbl, tbl->size);
--
2.19.1
^ permalink raw reply related
* Re: [Patch nf-next] nf_conntrack: fix error path in nf_conntrack_pernet_init()
From: Florian Westphal @ 2019-01-23 21:17 UTC (permalink / raw)
To: Cong Wang
Cc: netdev, netfilter-devel, syzbot+fcee88b2d87f0539dfe9,
Pablo Neira Ayuso, Jozsef Kadlecsik, Florian Westphal
In-Reply-To: <20190123205857.8107-1-xiyou.wangcong@gmail.com>
Cong Wang <xiyou.wangcong@gmail.com> wrote:
> When nf_ct_netns_get() fails, it should clean up itself,
> its caller doesn't need to call nf_conntrack_fini_net().
Thanks a lot for fixing this!
^ permalink raw reply
* [PATCH iproute2] f_flower: fix build with musl libc
From: Hans Dedecker @ 2019-01-23 21:02 UTC (permalink / raw)
To: stephen, netdev; +Cc: Hans Dedecker
XATTR_SIZE_MAX requires the usage of linux/limits.h; let's include it
Signed-off-by: Hans Dedecker <dedeckeh@gmail.com>
---
tc/f_flower.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/tc/f_flower.c b/tc/f_flower.c
index c5636667..9659e894 100644
--- a/tc/f_flower.c
+++ b/tc/f_flower.c
@@ -14,6 +14,7 @@
#include <unistd.h>
#include <string.h>
#include <net/if.h>
+#include <linux/limits.h>
#include <linux/if_arp.h>
#include <linux/if_ether.h>
#include <linux/ip.h>
--
2.19.1
^ permalink raw reply related
* [Patch nf-next] nf_conntrack: fix error path in nf_conntrack_pernet_init()
From: Cong Wang @ 2019-01-23 20:58 UTC (permalink / raw)
To: netdev
Cc: netfilter-devel, Cong Wang, syzbot+fcee88b2d87f0539dfe9,
Pablo Neira Ayuso, Jozsef Kadlecsik, Florian Westphal
When nf_ct_netns_get() fails, it should clean up itself,
its caller doesn't need to call nf_conntrack_fini_net().
nf_conntrack_init_net() is called after registering sysctl
and proc, so its cleanup function should be called before
unregistering sysctl and proc.
Fixes: ba3fbe663635 ("netfilter: nf_conntrack: provide modparam to always register conntrack hooks")
Fixes: b884fa461776 ("netfilter: conntrack: unify sysctl handling")
Reported-and-tested-by: syzbot+fcee88b2d87f0539dfe9@syzkaller.appspotmail.com
Cc: Pablo Neira Ayuso <pablo@netfilter.org>
Cc: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
Cc: Florian Westphal <fw@strlen.de>
Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
---
net/netfilter/nf_conntrack_standalone.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c
index 8928a4d0933e..c2ae14c720b4 100644
--- a/net/netfilter/nf_conntrack_standalone.c
+++ b/net/netfilter/nf_conntrack_standalone.c
@@ -1115,11 +1115,11 @@ static int nf_conntrack_pernet_init(struct net *net)
return 0;
out_hooks:
- nf_conntrack_fini_net(net);
+ nf_conntrack_cleanup_net(net);
out_init_net:
nf_conntrack_standalone_fini_proc(net);
out_proc:
- nf_conntrack_cleanup_net(net);
+ nf_conntrack_standalone_fini_sysctl(net);
return ret;
}
--
2.20.1
^ permalink raw reply related
* [PATCH v5 4/4] Bluetooth: btusb: Use the cmd_timeout method to reset the Intel BT chip
From: Rajat Jain @ 2019-01-23 20:57 UTC (permalink / raw)
To: Marcel Holtmann, Johan Hedberg, Greg Kroah-Hartman,
David S. Miller, Dmitry Torokhov, Rajat Jain, Alex Hung,
linux-bluetooth, linux-kernel, linux-usb, netdev
Cc: rajatxjain, dtor, raghuram.hegde, chethan.tumkur.narayan,
sukumar.ghorai
In-Reply-To: <20190123205725.239661-1-rajatja@google.com>
If the platform provides it, use the reset gpio to reset the Intel BT
chip, as part of cmd_timeout handling. This has been found helpful on
Intel bluetooth controllers where the firmware gets stuck and the only
way out is a hard reset pin provided by the platform.
Signed-off-by: Rajat Jain <rajatja@google.com>
---
v5: Rename the hook to cmd_timeout, and wait for 5 timeouts before
resetting the device.
v4: Use data->flags instead of clearing the quirk in btusb_hw_reset()
v3: Better error handling for gpiod_get_optional()
v2: Handle the EPROBE_DEFER case.
drivers/bluetooth/btusb.c | 54 +++++++++++++++++++++++++++++++++++++++
1 file changed, 54 insertions(+)
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 4761499db9ee..8949ea30a1bc 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -29,6 +29,7 @@
#include <linux/of_device.h>
#include <linux/of_irq.h>
#include <linux/suspend.h>
+#include <linux/gpio/consumer.h>
#include <asm/unaligned.h>
#include <net/bluetooth/bluetooth.h>
@@ -439,6 +440,7 @@ static const struct dmi_system_id btusb_needs_reset_resume_table[] = {
#define BTUSB_BOOTING 9
#define BTUSB_DIAG_RUNNING 10
#define BTUSB_OOB_WAKE_ENABLED 11
+#define BTUSB_HW_RESET_ACTIVE 12
struct btusb_data {
struct hci_dev *hdev;
@@ -476,6 +478,8 @@ struct btusb_data {
struct usb_endpoint_descriptor *diag_tx_ep;
struct usb_endpoint_descriptor *diag_rx_ep;
+ struct gpio_desc *reset_gpio;
+
__u8 cmdreq_type;
__u8 cmdreq;
@@ -489,8 +493,39 @@ struct btusb_data {
int (*setup_on_usb)(struct hci_dev *hdev);
int oob_wake_irq; /* irq for out-of-band wake-on-bt */
+ unsigned num_cmd_timeout;
};
+
+static void btusb_intel_cmd_timeout(struct hci_dev *hdev,
+ struct hci_command_hdr *cmd)
+{
+ struct btusb_data *data = hci_get_drvdata(hdev);
+ struct gpio_desc *reset_gpio = data->reset_gpio;
+
+ bt_dev_err(hdev, "btusb num_cmd_timeout = %u", ++data->num_cmd_timeout);
+
+ if (data->num_cmd_timeout < 5)
+ return;
+
+ /*
+ * Toggle the hard reset line if the platform provides one. The reset
+ * is going to yank the device off the USB and then replug. So doing
+ * once is enough. The cleanup is handled correctly on the way out
+ * (standard USB disconnect), and the new device is detected cleanly
+ * and bound to the driver again like it should be.
+ */
+ if (test_and_set_bit(BTUSB_HW_RESET_ACTIVE, &data->flags)) {
+ bt_dev_err(hdev, "last reset failed? Not resetting again");
+ return;
+ }
+
+ bt_dev_err(hdev, "Initiating HW reset via gpio");
+ gpiod_set_value(reset_gpio, 1);
+ mdelay(100);
+ gpiod_set_value(reset_gpio, 0);
+}
+
static inline void btusb_free_frags(struct btusb_data *data)
{
unsigned long flags;
@@ -2915,6 +2950,7 @@ static int btusb_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
struct usb_endpoint_descriptor *ep_desc;
+ struct gpio_desc *reset_gpio;
struct btusb_data *data;
struct hci_dev *hdev;
unsigned ifnum_base;
@@ -3028,6 +3064,15 @@ static int btusb_probe(struct usb_interface *intf,
SET_HCIDEV_DEV(hdev, &intf->dev);
+ reset_gpio = gpiod_get_optional(&data->udev->dev, "reset",
+ GPIOD_OUT_LOW);
+ if (IS_ERR(reset_gpio)) {
+ err = PTR_ERR(reset_gpio);
+ goto out_free_dev;
+ } else if (reset_gpio) {
+ data->reset_gpio = reset_gpio;
+ }
+
hdev->open = btusb_open;
hdev->close = btusb_close;
hdev->flush = btusb_flush;
@@ -3085,6 +3130,8 @@ static int btusb_probe(struct usb_interface *intf,
set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks);
set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks);
set_bit(HCI_QUIRK_NON_PERSISTENT_DIAG, &hdev->quirks);
+ if (data->reset_gpio)
+ hdev->cmd_timeout = btusb_intel_cmd_timeout;
}
if (id->driver_info & BTUSB_INTEL_NEW) {
@@ -3097,6 +3144,8 @@ static int btusb_probe(struct usb_interface *intf,
set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks);
set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks);
set_bit(HCI_QUIRK_NON_PERSISTENT_DIAG, &hdev->quirks);
+ if (data->reset_gpio)
+ hdev->cmd_timeout = btusb_intel_cmd_timeout;
}
if (id->driver_info & BTUSB_MARVELL)
@@ -3226,6 +3275,8 @@ static int btusb_probe(struct usb_interface *intf,
return 0;
out_free_dev:
+ if (data->reset_gpio)
+ gpiod_put(data->reset_gpio);
hci_free_dev(hdev);
return err;
}
@@ -3269,6 +3320,9 @@ static void btusb_disconnect(struct usb_interface *intf)
if (data->oob_wake_irq)
device_init_wakeup(&data->udev->dev, false);
+ if (data->reset_gpio)
+ gpiod_put(data->reset_gpio);
+
hci_free_dev(hdev);
}
--
2.20.1.321.g9e740568ce-goog
^ permalink raw reply related
* [PATCH v5 3/4] Bluetooth: Allow driver specific cmd timeout handling
From: Rajat Jain @ 2019-01-23 20:57 UTC (permalink / raw)
To: Marcel Holtmann, Johan Hedberg, Greg Kroah-Hartman,
David S. Miller, Dmitry Torokhov, Rajat Jain, Alex Hung,
linux-bluetooth, linux-kernel, linux-usb, netdev
Cc: rajatxjain, dtor, raghuram.hegde, chethan.tumkur.narayan,
sukumar.ghorai
In-Reply-To: <20190123205725.239661-1-rajatja@google.com>
Add a hook to allow the BT driver to do device or command specific
handling in case of timeouts. This is to be used by Intel driver to
reset the device after certain number of timeouts.
Signed-off-by: Rajat Jain <rajatja@google.com>
---
v5: Drop the quirk, and rename the hook function to cmd_timeout()
v4: same as v1
v3: same as v1
v2: same as v1
include/net/bluetooth/hci_core.h | 1 +
net/bluetooth/hci_core.c | 10 ++++++++--
2 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index e5ea633ea368..624d5f2b1f36 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -437,6 +437,7 @@ struct hci_dev {
int (*post_init)(struct hci_dev *hdev);
int (*set_diag)(struct hci_dev *hdev, bool enable);
int (*set_bdaddr)(struct hci_dev *hdev, const bdaddr_t *bdaddr);
+ void (*cmd_timeout)(struct hci_dev *hdev, struct hci_command_hdr *cmd);
};
#define HCI_PHY_HANDLE(handle) (handle & 0xff)
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 7352fe85674b..c6917f57581a 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -2568,16 +2568,22 @@ static void hci_cmd_timeout(struct work_struct *work)
{
struct hci_dev *hdev = container_of(work, struct hci_dev,
cmd_timer.work);
+ struct hci_command_hdr *sent = NULL;
if (hdev->sent_cmd) {
- struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data;
- u16 opcode = __le16_to_cpu(sent->opcode);
+ u16 opcode;
+
+ sent = (void *) hdev->sent_cmd->data;
+ opcode = __le16_to_cpu(sent->opcode);
bt_dev_err(hdev, "command 0x%4.4x tx timeout", opcode);
} else {
bt_dev_err(hdev, "command tx timeout");
}
+ if (hdev->cmd_timeout)
+ hdev->cmd_timeout(hdev, sent);
+
atomic_set(&hdev->cmd_cnt, 1);
queue_work(hdev->workqueue, &hdev->cmd_work);
}
--
2.20.1.321.g9e740568ce-goog
^ permalink raw reply related
* [PATCH v5 2/4] usb: assign ACPI companions for embedded USB devices
From: Rajat Jain @ 2019-01-23 20:57 UTC (permalink / raw)
To: Marcel Holtmann, Johan Hedberg, Greg Kroah-Hartman,
David S. Miller, Dmitry Torokhov, Rajat Jain, Alex Hung,
linux-bluetooth, linux-kernel, linux-usb, netdev
Cc: rajatxjain, dtor, raghuram.hegde, chethan.tumkur.narayan,
sukumar.ghorai
In-Reply-To: <20190123205725.239661-1-rajatja@google.com>
From: Dmitry Torokhov <dtor@chromium.org>
USB devices permanently connected to USB ports may be described in ACPI
tables and share ACPI devices with ports they are connected to. See [1]
for details.
This will allow us to describe sideband resources for devices, such as,
for example, hard reset line for BT USB controllers.
[1] https://docs.microsoft.com/en-us/windows-hardware/drivers/bringup/other-acpi-namespace-objects#acpi-namespace-hierarchy-and-adr-for-embedded-usb-devices
Signed-off-by: Dmitry Torokhov <dtor@chromium.org>
Signed-off-by: Rajat Jain <rajatja@google.com> (changed how we get the usb_port)
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Tested-by: Sukumar Ghorai <sukumar.ghorai@intel.com>
---
v5: same as v4
v4: Add Acked-by and Tested-by in signatures.
v3: same as v1
v2: same as v1
drivers/usb/core/usb-acpi.c | 44 +++++++++++++++++++++++++++++--------
1 file changed, 35 insertions(+), 9 deletions(-)
diff --git a/drivers/usb/core/usb-acpi.c b/drivers/usb/core/usb-acpi.c
index 8ff73c83e8e8..9043d7242d67 100644
--- a/drivers/usb/core/usb-acpi.c
+++ b/drivers/usb/core/usb-acpi.c
@@ -200,30 +200,56 @@ static struct acpi_device *
usb_acpi_find_companion_for_device(struct usb_device *udev)
{
struct acpi_device *adev;
+ struct usb_port *port_dev;
+ struct usb_hub *hub;
+
+ if (!udev->parent) {
+ /* root hub is only child (_ADR=0) under its parent, the HC */
+ adev = ACPI_COMPANION(udev->dev.parent);
+ return acpi_find_child_device(adev, 0, false);
+ }
- if (!udev->parent)
+ hub = usb_hub_to_struct_hub(udev->parent);
+ if (!hub)
return NULL;
- /* root hub is only child (_ADR=0) under its parent, the HC */
- adev = ACPI_COMPANION(udev->dev.parent);
- return acpi_find_child_device(adev, 0, false);
+ /*
+ * This is an embedded USB device connected to a port and such
+ * devices share port's ACPI companion.
+ */
+ port_dev = hub->ports[udev->portnum - 1];
+ return usb_acpi_get_companion_for_port(port_dev);
}
-
static struct acpi_device *usb_acpi_find_companion(struct device *dev)
{
/*
- * In the ACPI DSDT table, only usb root hub and usb ports are
- * acpi device nodes. The hierarchy like following.
+ * The USB hierarchy like following:
+ *
* Device (EHC1)
* Device (HUBN)
* Device (PR01)
* Device (PR11)
* Device (PR12)
+ * Device (FN12)
+ * Device (FN13)
* Device (PR13)
* ...
- * So all binding process is divided into two parts. binding
- * root hub and usb ports.
+ * where HUBN is root hub, and PRNN are USB ports and devices
+ * connected to them, and FNNN are individualk functions for
+ * connected composite USB devices. PRNN and FNNN may contain
+ * _CRS and other methods describing sideband resources for
+ * the connected device.
+ *
+ * On the kernel side both root hub and embedded USB devices are
+ * represented as instances of usb_device structure, and ports
+ * are represented as usb_port structures, so the whole process
+ * is split into 2 parts: finding companions for devices and
+ * finding companions for ports.
+ *
+ * Note that we do not handle individual functions of composite
+ * devices yet, for that we would need to assign companions to
+ * devices corresponding to USB interfaces.
*/
if (is_usb_device(dev))
return usb_acpi_find_companion_for_device(to_usb_device(dev));
--
2.20.1.321.g9e740568ce-goog
^ permalink raw reply related
* [PATCH v5 1/4] usb: split code locating ACPI companion into port and device
From: Rajat Jain @ 2019-01-23 20:57 UTC (permalink / raw)
To: Marcel Holtmann, Johan Hedberg, Greg Kroah-Hartman,
David S. Miller, Dmitry Torokhov, Rajat Jain, Alex Hung,
linux-bluetooth, linux-kernel, linux-usb, netdev
Cc: rajatxjain, dtor, raghuram.hegde, chethan.tumkur.narayan,
sukumar.ghorai
In-Reply-To: <20181117010748.24347-1-rajatja@google.com>
From: Dmitry Torokhov <dtor@chromium.org>
In preparation for handling embedded USB devices let's split
usb_acpi_find_companion() into usb_acpi_find_companion_for_device() and
usb_acpi_find_companion_for_port().
Signed-off-by: Dmitry Torokhov <dtor@chromium.org>
Signed-off-by: Rajat Jain <rajatja@google.com>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Tested-by: Sukumar Ghorai <sukumar.ghorai@intel.com>
---
v5: same as v4
v4: Add Acked-by and Tested-by in signatures.
v3: same as v1
v2: same as v1
drivers/usb/core/usb-acpi.c | 133 +++++++++++++++++++-----------------
1 file changed, 72 insertions(+), 61 deletions(-)
diff --git a/drivers/usb/core/usb-acpi.c b/drivers/usb/core/usb-acpi.c
index e221861b3187..8ff73c83e8e8 100644
--- a/drivers/usb/core/usb-acpi.c
+++ b/drivers/usb/core/usb-acpi.c
@@ -139,12 +139,79 @@ static struct acpi_device *usb_acpi_find_port(struct acpi_device *parent,
return acpi_find_child_device(parent, raw, false);
}
-static struct acpi_device *usb_acpi_find_companion(struct device *dev)
+static struct acpi_device *
+usb_acpi_get_companion_for_port(struct usb_port *port_dev)
{
struct usb_device *udev;
struct acpi_device *adev;
acpi_handle *parent_handle;
+ int port1;
+
+ /* Get the struct usb_device point of port's hub */
+ udev = to_usb_device(port_dev->dev.parent->parent);
+
+ /*
+ * The root hub ports' parent is the root hub. The non-root-hub
+ * ports' parent is the parent hub port which the hub is
+ * connected to.
+ */
+ if (!udev->parent) {
+ adev = ACPI_COMPANION(&udev->dev);
+ port1 = usb_hcd_find_raw_port_number(bus_to_hcd(udev->bus),
+ port_dev->portnum);
+ } else {
+ parent_handle = usb_get_hub_port_acpi_handle(udev->parent,
+ udev->portnum);
+ if (!parent_handle)
+ return NULL;
+
+ acpi_bus_get_device(parent_handle, &adev);
+ port1 = port_dev->portnum;
+ }
+
+ return usb_acpi_find_port(adev, port1);
+}
+
+static struct acpi_device *
+usb_acpi_find_companion_for_port(struct usb_port *port_dev)
+{
+ struct acpi_device *adev;
+ struct acpi_pld_info *pld;
+ acpi_handle *handle;
+ acpi_status status;
+
+ adev = usb_acpi_get_companion_for_port(port_dev);
+ if (!adev)
+ return NULL;
+
+ handle = adev->handle;
+ status = acpi_get_physical_device_location(handle, &pld);
+ if (!ACPI_FAILURE(status) && pld) {
+ port_dev->location = USB_ACPI_LOCATION_VALID
+ | pld->group_token << 8 | pld->group_position;
+ port_dev->connect_type = usb_acpi_get_connect_type(handle, pld);
+ ACPI_FREE(pld);
+ }
+ return adev;
+}
+
+static struct acpi_device *
+usb_acpi_find_companion_for_device(struct usb_device *udev)
+{
+ struct acpi_device *adev;
+
+ if (!udev->parent)
+ return NULL;
+
+ /* root hub is only child (_ADR=0) under its parent, the HC */
+ adev = ACPI_COMPANION(udev->dev.parent);
+ return acpi_find_child_device(adev, 0, false);
+}
+
+
+static struct acpi_device *usb_acpi_find_companion(struct device *dev)
+{
/*
* In the ACPI DSDT table, only usb root hub and usb ports are
* acpi device nodes. The hierarchy like following.
@@ -158,66 +225,10 @@ static struct acpi_device *usb_acpi_find_companion(struct device *dev)
* So all binding process is divided into two parts. binding
* root hub and usb ports.
*/
- if (is_usb_device(dev)) {
- udev = to_usb_device(dev);
- if (udev->parent)
- return NULL;
-
- /* root hub is only child (_ADR=0) under its parent, the HC */
- adev = ACPI_COMPANION(dev->parent);
- return acpi_find_child_device(adev, 0, false);
- } else if (is_usb_port(dev)) {
- struct usb_port *port_dev = to_usb_port(dev);
- int port1 = port_dev->portnum;
- struct acpi_pld_info *pld;
- acpi_handle *handle;
- acpi_status status;
-
- /* Get the struct usb_device point of port's hub */
- udev = to_usb_device(dev->parent->parent);
-
- /*
- * The root hub ports' parent is the root hub. The non-root-hub
- * ports' parent is the parent hub port which the hub is
- * connected to.
- */
- if (!udev->parent) {
- struct usb_hcd *hcd = bus_to_hcd(udev->bus);
- int raw;
-
- raw = usb_hcd_find_raw_port_number(hcd, port1);
-
- adev = usb_acpi_find_port(ACPI_COMPANION(&udev->dev),
- raw);
-
- if (!adev)
- return NULL;
- } else {
- parent_handle =
- usb_get_hub_port_acpi_handle(udev->parent,
- udev->portnum);
- if (!parent_handle)
- return NULL;
-
- acpi_bus_get_device(parent_handle, &adev);
-
- adev = usb_acpi_find_port(adev, port1);
-
- if (!adev)
- return NULL;
- }
- handle = adev->handle;
- status = acpi_get_physical_device_location(handle, &pld);
- if (ACPI_FAILURE(status) || !pld)
- return adev;
-
- port_dev->location = USB_ACPI_LOCATION_VALID
- | pld->group_token << 8 | pld->group_position;
- port_dev->connect_type = usb_acpi_get_connect_type(handle, pld);
- ACPI_FREE(pld);
-
- return adev;
- }
+ if (is_usb_device(dev))
+ return usb_acpi_find_companion_for_device(to_usb_device(dev));
+ else if (is_usb_port(dev))
+ return usb_acpi_find_companion_for_port(to_usb_port(dev));
return NULL;
}
--
2.20.1.321.g9e740568ce-goog
^ permalink raw reply related
* Re: [Patch iproute2] tc: add hit counter for matchall
From: Stephen Hemminger @ 2019-01-23 20:47 UTC (permalink / raw)
To: Cong Wang
Cc: netdev, Martin Olsson, Jamal Hadi Salim, Jiri Pirko, David Ahern
In-Reply-To: <20190117211855.31030-1-xiyou.wangcong@gmail.com>
On Thu, 17 Jan 2019 13:18:55 -0800
Cong Wang <xiyou.wangcong@gmail.com> wrote:
>
> + if (tb[TCA_MATCHALL_PCNT]) {
> + if (RTA_PAYLOAD(tb[TCA_MATCHALL_PCNT]) < sizeof(*pf)) {
> + print_string(PRINT_FP, NULL, "Broken perf counters\n", NULL);
This the wrong way to print an error message with iproute2 suite.
The correct answer is simple.
fprintf(stderr, "Broken perf counters\n");
and better yet give a more informative message that says what is incorrect.
^ permalink raw reply
* Re: KASAN: use-after-free Read in refcount_inc_not_zero_checked
From: syzbot @ 2019-01-23 20:45 UTC (permalink / raw)
To: davem, linux-hams, linux-kernel, netdev, ralf, syzkaller-bugs
In-Reply-To: <000000000000d78798057e773261@google.com>
syzbot has found a reproducer for the following crash on:
HEAD commit: 333478a7eb21 Merge branch 'for-rc' of git://git.kernel.org..
git tree: upstream
console output: https://syzkaller.appspot.com/x/log.txt?x=14ec4628c00000
kernel config: https://syzkaller.appspot.com/x/.config?x=505743eba4e4f68
dashboard link: https://syzkaller.appspot.com/bug?extid=defa700d16f1bd1b9a05
compiler: gcc (GCC) 9.0.0 20181231 (experimental)
syz repro: https://syzkaller.appspot.com/x/repro.syz?x=142f7590c00000
IMPORTANT: if you fix the bug, please add the following tag to the commit:
Reported-by: syzbot+defa700d16f1bd1b9a05@syzkaller.appspotmail.com
IPv6: ADDRCONF(NETDEV_UP): vxcan1: link is not ready
8021q: adding VLAN 0 to HW filter on device batadv0
IPVS: ftp: loaded support on port[0] = 21
chnl_net:caif_netlink_parms(): no params data found
==================================================================
BUG: KASAN: use-after-free in atomic_read
include/asm-generic/atomic-instrumented.h:21 [inline]
BUG: KASAN: use-after-free in refcount_inc_not_zero_checked+0x91/0x2e0
lib/refcount.c:120
Read of size 4 at addr ffff888089bba440 by task syz-executor5/11381
CPU: 1 PID: 11381 Comm: syz-executor5 Not tainted 5.0.0-rc3+ #40
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS
Google 01/01/2011
Call Trace:
__dump_stack lib/dump_stack.c:77 [inline]
dump_stack+0x1db/0x2d0 lib/dump_stack.c:113
print_address_description.cold+0x7c/0x20d mm/kasan/report.c:187
kasan_report.cold+0x1b/0x40 mm/kasan/report.c:317
check_memory_region_inline mm/kasan/generic.c:185 [inline]
check_memory_region+0x123/0x190 mm/kasan/generic.c:191
kasan_check_read+0x11/0x20 mm/kasan/common.c:100
atomic_read include/asm-generic/atomic-instrumented.h:21 [inline]
refcount_inc_not_zero_checked+0x91/0x2e0 lib/refcount.c:120
refcount_inc_checked+0x17/0x70 lib/refcount.c:153
sock_hold include/net/sock.h:647 [inline]
nr_release+0x62/0x3c0 net/netrom/af_netrom.c:523
__sock_release+0xd3/0x250 net/socket.c:579
sock_close+0x1b/0x30 net/socket.c:1141
__fput+0x3c5/0xb10 fs/file_table.c:278
____fput+0x16/0x20 fs/file_table.c:309
task_work_run+0x1f4/0x2b0 kernel/task_work.c:113
exit_task_work include/linux/task_work.h:22 [inline]
do_exit+0xad7/0x26e0 kernel/exit.c:867
do_group_exit+0x177/0x430 kernel/exit.c:971
get_signal+0x8b4/0x19b0 kernel/signal.c:2517
do_signal+0x91/0x1ea0 arch/x86/kernel/signal.c:816
exit_to_usermode_loop+0x2f7/0x3b0 arch/x86/entry/common.c:162
prepare_exit_to_usermode arch/x86/entry/common.c:197 [inline]
syscall_return_slowpath arch/x86/entry/common.c:268 [inline]
do_syscall_64+0x696/0x800 arch/x86/entry/common.c:293
entry_SYSCALL_64_after_hwframe+0x49/0xbe
RIP: 0033:0x458099
Code: 6d b7 fb ff c3 66 2e 0f 1f 84 00 00 00 00 00 66 90 48 89 f8 48 89 f7
48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff
ff 0f 83 3b b7 fb ff c3 66 2e 0f 1f 84 00 00 00 00
RSP: 002b:00007f7c8a6a7cf8 EFLAGS: 00000246 ORIG_RAX: 00000000000000ca
RAX: fffffffffffffe00 RBX: 000000000073c228 RCX: 0000000000458099
RDX: 0000000000000000 RSI: 0000000000000080 RDI: 000000000073c228
RBP: 000000000073c220 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 000000000073c22c
R13: 00007ffc1cd8e9ef R14: 00007f7c8a6a89c0 R15: 0000000000000005
Allocated by task 11350:
save_stack+0x45/0xd0 mm/kasan/common.c:73
set_track mm/kasan/common.c:85 [inline]
__kasan_kmalloc mm/kasan/common.c:496 [inline]
__kasan_kmalloc.constprop.0+0xcf/0xe0 mm/kasan/common.c:469
kasan_kmalloc+0x9/0x10 mm/kasan/common.c:504
__do_kmalloc mm/slab.c:3711 [inline]
__kmalloc+0x15c/0x740 mm/slab.c:3720
kmalloc include/linux/slab.h:550 [inline]
sk_prot_alloc+0x19c/0x2e0 net/core/sock.c:1477
sk_alloc+0xd7/0x1690 net/core/sock.c:1531
nr_create+0xb9/0x5e0 net/netrom/af_netrom.c:436
__sock_create+0x532/0x930 net/socket.c:1277
sock_create net/socket.c:1317 [inline]
__sys_socket+0x106/0x260 net/socket.c:1347
__do_sys_socket net/socket.c:1356 [inline]
__se_sys_socket net/socket.c:1354 [inline]
__x64_sys_socket+0x73/0xb0 net/socket.c:1354
do_syscall_64+0x1a3/0x800 arch/x86/entry/common.c:290
entry_SYSCALL_64_after_hwframe+0x49/0xbe
Freed by task 11170:
save_stack+0x45/0xd0 mm/kasan/common.c:73
set_track mm/kasan/common.c:85 [inline]
__kasan_slab_free+0x102/0x150 mm/kasan/common.c:458
kasan_slab_free+0xe/0x10 mm/kasan/common.c:466
__cache_free mm/slab.c:3487 [inline]
kfree+0xcf/0x230 mm/slab.c:3806
sk_prot_free net/core/sock.c:1514 [inline]
__sk_destruct+0x76d/0xa60 net/core/sock.c:1596
sk_destruct+0x7b/0x90 net/core/sock.c:1604
__sk_free+0xce/0x300 net/core/sock.c:1615
sk_free+0x42/0x50 net/core/sock.c:1626
sock_put include/net/sock.h:1707 [inline]
nr_heartbeat_expiry+0x489/0x520 net/netrom/nr_timer.c:130
call_timer_fn+0x254/0x900 kernel/time/timer.c:1325
expire_timers kernel/time/timer.c:1362 [inline]
__run_timers+0x6fc/0xd50 kernel/time/timer.c:1681
run_timer_softirq+0x52/0xb0 kernel/time/timer.c:1694
__do_softirq+0x30b/0xb11 kernel/softirq.c:292
The buggy address belongs to the object at ffff888089bba3c0
which belongs to the cache kmalloc-2k of size 2048
The buggy address is located 128 bytes inside of
2048-byte region [ffff888089bba3c0, ffff888089bbabc0)
The buggy address belongs to the page:
page:ffffea000226ee80 count:1 mapcount:0 mapping:ffff88812c3f0c40
index:0xffff888089bbb4c0 compound_mapcount: 0
flags: 0x1fffc0000010200(slab|head)
raw: 01fffc0000010200 ffffea0002608f08 ffffea0002501688 ffff88812c3f0c40
raw: ffff888089bbb4c0 ffff888089bba3c0 0000000100000001 0000000000000000
page dumped because: kasan: bad access detected
Memory state around the buggy address:
ffff888089bba300: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
ffff888089bba380: fc fc fc fc fc fc fc fc fb fb fb fb fb fb fb fb
> ffff888089bba400: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
^
ffff888089bba480: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
ffff888089bba500: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
==================================================================
^ permalink raw reply
* Re: [Patch iproute2] tc: add performance counters for basic filter
From: Stephen Hemminger @ 2019-01-23 20:43 UTC (permalink / raw)
To: Cong Wang; +Cc: netdev, Jamal Hadi Salim, Jiri Pirko, David Ahern
In-Reply-To: <20190123064145.26169-1-xiyou.wangcong@gmail.com>
On Tue, 22 Jan 2019 22:41:45 -0800
Cong Wang <xiyou.wangcong@gmail.com> wrote:
> + if (tb[TCA_BASIC_PCNT]) {
> + if (RTA_PAYLOAD(tb[TCA_BASIC_PCNT]) < sizeof(*pf)) {
> + fprintf(f, "Broken perf counters\n");
> + return -1;
Errors should go to stderr not f (which is stdout).
^ permalink raw reply
* Re: [Intel-gfx] [PATCH 1/3] treewide: Lift switch variables out of switches
From: Kees Cook @ 2019-01-23 20:36 UTC (permalink / raw)
To: Matthew Wilcox
Cc: Jani Nikula, Greg KH, dev, Ard Biesheuvel, Network Development,
intel-gfx, linux-usb, LKML, Maling list - DRI developers,
Linux-MM, linux-security-module, Kernel Hardening,
intel-wired-lan, linux-fsdevel@vger.kernel.org, xen-devel,
Laura Abbott, linux-kbuild, Alexander Popov
In-Reply-To: <20190123191802.GB15311@bombadil.infradead.org>
On Thu, Jan 24, 2019 at 8:18 AM Matthew Wilcox <willy@infradead.org> wrote:
>
> On Wed, Jan 23, 2019 at 04:17:30PM +0200, Jani Nikula wrote:
> > Can't have:
> >
> > switch (i) {
> > int j;
> > case 0:
> > /* ... */
> > }
> >
> > because it can't be turned into:
> >
> > switch (i) {
> > int j = 0; /* not valid C */
> > case 0:
> > /* ... */
> > }
> >
> > but can have e.g.:
> >
> > switch (i) {
> > case 0:
> > {
> > int j = 0;
> > /* ... */
> > }
> > }
> >
> > I think Kees' approach of moving such variable declarations to the
> > enclosing block scope is better than adding another nesting block.
>
> Another nesting level would be bad, but I think this is OK:
>
> switch (i) {
> case 0: {
> int j = 0;
> /* ... */
> }
> case 1: {
> void *p = q;
> /* ... */
> }
> }
>
> I can imagine Kees' patch might have a bad effect on stack consumption,
> unless GCC can be relied on to be smart enough to notice the
> non-overlapping liveness of the vriables and use the same stack slots
> for both.
GCC is reasonable at this. The main issue, though, was most of these
places were using the variables in multiple case statements, so they
couldn't be limited to a single block (or they'd need to be manually
repeated in each block, which is even more ugly, IMO).
Whatever the consensus, I'm happy to tweak the patch.
Thanks!
--
Kees Cook
^ permalink raw reply
* [PATCH v2 net-next] lan743x: Provide Read/Write Access to on chip OTP
From: Bryan Whitehead @ 2019-01-23 20:18 UTC (permalink / raw)
To: davem; +Cc: netdev, UNGLinuxDriver
The LAN743x includes on chip One-Time-Programmable (OTP) memory.
This patch extends the ethtool EEPROM read/write interface to
access OTP memory space.
The currently existing interface is limited, as it does not
allow OTP read, and OTP writes are restricted to
offset==0, length==512, and data[0]==0xF3.
This patch removes these restrictions and adds a private flag
called OTP_ACCESS, which is used to switch between EEPROM, and
OTP modes.
The private flag OTP_ACCESS is configurable through the
ethtool --set-priv-flags command.
And visible through the
ethtool --show-priv-flags command.
By default OTP_ACCESS is false, and there for previously existing
EEPROM commands will work exactly the same. However now access to
OTP requires one extra step of setting OTP_ACCESS to true. This
flag controls the read, write, and length reporting, functions
of ethtool.
EEPROM presence is not checked when setting or clearing this flag.
If the EEPROM is not present, the user, as before, will need to
diagnose that using existing read and write function of ethtool,
while OTP_ACCESS is false.
Updates for V2:
Added comments as to why this patch is needed.
Added comments explaining that EEPROM presence is not check
when setting or clearing the OTP_ACCESS flag.
Added length checking to all otp/eeprom read/write functions.
Signed-off-by: Bryan Whitehead <Bryan.Whitehead@microchip.com>
---
drivers/net/ethernet/microchip/lan743x_ethtool.c | 217 ++++++++++++++++++-----
drivers/net/ethernet/microchip/lan743x_main.h | 17 +-
2 files changed, 182 insertions(+), 52 deletions(-)
diff --git a/drivers/net/ethernet/microchip/lan743x_ethtool.c b/drivers/net/ethernet/microchip/lan743x_ethtool.c
index 07c1eb6..3a0b289 100644
--- a/drivers/net/ethernet/microchip/lan743x_ethtool.c
+++ b/drivers/net/ethernet/microchip/lan743x_ethtool.c
@@ -14,61 +14,138 @@
#define EEPROM_INDICATOR_1 (0xA5)
#define EEPROM_INDICATOR_2 (0xAA)
#define EEPROM_MAC_OFFSET (0x01)
-#define MAX_EEPROM_SIZE 512
+#define MAX_EEPROM_SIZE (512)
+#define MAX_OTP_SIZE (1024)
#define OTP_INDICATOR_1 (0xF3)
#define OTP_INDICATOR_2 (0xF7)
-static int lan743x_otp_write(struct lan743x_adapter *adapter, u32 offset,
- u32 length, u8 *data)
+static int lan743x_otp_power_up(struct lan743x_adapter *adapter)
+{
+ u32 reg_value;
+
+ reg_value = lan743x_csr_read(adapter, OTP_PWR_DN);
+
+ if (reg_value & OTP_PWR_DN_PWRDN_N_) {
+ /* clear it and wait to be cleared */
+ reg_value &= ~OTP_PWR_DN_PWRDN_N_;
+ lan743x_csr_write(adapter, OTP_PWR_DN, reg_value);
+
+ usleep_range(100, 20000);
+ }
+
+ return 0;
+}
+
+static void lan743x_otp_power_down(struct lan743x_adapter *adapter)
+{
+ u32 reg_value;
+
+ reg_value = lan743x_csr_read(adapter, OTP_PWR_DN);
+ if (!(reg_value & OTP_PWR_DN_PWRDN_N_)) {
+ /* set power down bit */
+ reg_value |= OTP_PWR_DN_PWRDN_N_;
+ lan743x_csr_write(adapter, OTP_PWR_DN, reg_value);
+ }
+}
+
+static void lan743x_otp_set_address(struct lan743x_adapter *adapter,
+ u32 address)
+{
+ lan743x_csr_write(adapter, OTP_ADDR_HIGH, (address >> 8) & 0x03);
+ lan743x_csr_write(adapter, OTP_ADDR_LOW, address & 0xFF);
+}
+
+static void lan743x_otp_read_go(struct lan743x_adapter *adapter)
+{
+ lan743x_csr_write(adapter, OTP_FUNC_CMD, OTP_FUNC_CMD_READ_);
+ lan743x_csr_write(adapter, OTP_CMD_GO, OTP_CMD_GO_GO_);
+}
+
+static int lan743x_otp_wait_till_not_busy(struct lan743x_adapter *adapter)
{
unsigned long timeout;
- u32 buf;
+ u32 reg_val;
+
+ timeout = jiffies + HZ;
+ do {
+ if (time_after(jiffies, timeout)) {
+ netif_warn(adapter, drv, adapter->netdev,
+ "Timeout on OTP_STATUS completion\n");
+ return -EIO;
+ }
+ udelay(1);
+ reg_val = lan743x_csr_read(adapter, OTP_STATUS);
+ } while (reg_val & OTP_STATUS_BUSY_);
+
+ return 0;
+}
+
+static int lan743x_otp_read(struct lan743x_adapter *adapter, u32 offset,
+ u32 length, u8 *data)
+{
+ int ret;
int i;
- buf = lan743x_csr_read(adapter, OTP_PWR_DN);
+ if (offset + length > MAX_OTP_SIZE)
+ return -EINVAL;
- if (buf & OTP_PWR_DN_PWRDN_N_) {
- /* clear it and wait to be cleared */
- lan743x_csr_write(adapter, OTP_PWR_DN, 0);
-
- timeout = jiffies + HZ;
- do {
- udelay(1);
- buf = lan743x_csr_read(adapter, OTP_PWR_DN);
- if (time_after(jiffies, timeout)) {
- netif_warn(adapter, drv, adapter->netdev,
- "timeout on OTP_PWR_DN completion\n");
- return -EIO;
- }
- } while (buf & OTP_PWR_DN_PWRDN_N_);
+ ret = lan743x_otp_power_up(adapter);
+ if (ret < 0)
+ return ret;
+
+ ret = lan743x_otp_wait_till_not_busy(adapter);
+ if (ret < 0)
+ return ret;
+
+ for (i = 0; i < length; i++) {
+ lan743x_otp_set_address(adapter, offset + i);
+
+ lan743x_otp_read_go(adapter);
+ ret = lan743x_otp_wait_till_not_busy(adapter);
+ if (ret < 0)
+ return ret;
+ data[i] = lan743x_csr_read(adapter, OTP_READ_DATA);
}
+ lan743x_otp_power_down(adapter);
+
+ return 0;
+}
+
+static int lan743x_otp_write(struct lan743x_adapter *adapter, u32 offset,
+ u32 length, u8 *data)
+{
+ int ret;
+ int i;
+
+ if (offset + length > MAX_OTP_SIZE)
+ return -EINVAL;
+
+ ret = lan743x_otp_power_up(adapter);
+ if (ret < 0)
+ return ret;
+
+ ret = lan743x_otp_wait_till_not_busy(adapter);
+ if (ret < 0)
+ return ret;
+
/* set to BYTE program mode */
lan743x_csr_write(adapter, OTP_PRGM_MODE, OTP_PRGM_MODE_BYTE_);
for (i = 0; i < length; i++) {
- lan743x_csr_write(adapter, OTP_ADDR1,
- ((offset + i) >> 8) &
- OTP_ADDR1_15_11_MASK_);
- lan743x_csr_write(adapter, OTP_ADDR2,
- ((offset + i) &
- OTP_ADDR2_10_3_MASK_));
+ lan743x_otp_set_address(adapter, offset + i);
+
lan743x_csr_write(adapter, OTP_PRGM_DATA, data[i]);
lan743x_csr_write(adapter, OTP_TST_CMD, OTP_TST_CMD_PRGVRFY_);
lan743x_csr_write(adapter, OTP_CMD_GO, OTP_CMD_GO_GO_);
- timeout = jiffies + HZ;
- do {
- udelay(1);
- buf = lan743x_csr_read(adapter, OTP_STATUS);
- if (time_after(jiffies, timeout)) {
- netif_warn(adapter, drv, adapter->netdev,
- "Timeout on OTP_STATUS completion\n");
- return -EIO;
- }
- } while (buf & OTP_STATUS_BUSY_);
+ ret = lan743x_otp_wait_till_not_busy(adapter);
+ if (ret < 0)
+ return ret;
}
+ lan743x_otp_power_down(adapter);
+
return 0;
}
@@ -120,6 +197,9 @@ static int lan743x_eeprom_read(struct lan743x_adapter *adapter,
u32 val;
int i;
+ if (offset + length > MAX_EEPROM_SIZE)
+ return -EINVAL;
+
retval = lan743x_eeprom_confirm_not_busy(adapter);
if (retval)
return retval;
@@ -148,6 +228,9 @@ static int lan743x_eeprom_write(struct lan743x_adapter *adapter,
u32 val;
int i;
+ if (offset + length > MAX_EEPROM_SIZE)
+ return -EINVAL;
+
retval = lan743x_eeprom_confirm_not_busy(adapter);
if (retval)
return retval;
@@ -207,6 +290,11 @@ static void lan743x_ethtool_set_msglevel(struct net_device *netdev,
static int lan743x_ethtool_get_eeprom_len(struct net_device *netdev)
{
+ struct lan743x_adapter *adapter = netdev_priv(netdev);
+
+ if (adapter->flags & LAN743X_ADAPTER_FLAG_OTP)
+ return MAX_OTP_SIZE;
+
return MAX_EEPROM_SIZE;
}
@@ -214,8 +302,14 @@ static int lan743x_ethtool_get_eeprom(struct net_device *netdev,
struct ethtool_eeprom *ee, u8 *data)
{
struct lan743x_adapter *adapter = netdev_priv(netdev);
+ int ret = 0;
+
+ if (adapter->flags & LAN743X_ADAPTER_FLAG_OTP)
+ ret = lan743x_otp_read(adapter, ee->offset, ee->len, data);
+ else
+ ret = lan743x_eeprom_read(adapter, ee->offset, ee->len, data);
- return lan743x_eeprom_read(adapter, ee->offset, ee->len, data);
+ return ret;
}
static int lan743x_ethtool_set_eeprom(struct net_device *netdev,
@@ -224,17 +318,18 @@ static int lan743x_ethtool_set_eeprom(struct net_device *netdev,
struct lan743x_adapter *adapter = netdev_priv(netdev);
int ret = -EINVAL;
- if (ee->magic == LAN743X_EEPROM_MAGIC)
- ret = lan743x_eeprom_write(adapter, ee->offset, ee->len,
- data);
- /* Beware! OTP is One Time Programming ONLY!
- * So do some strict condition check before messing up
- */
- else if ((ee->magic == LAN743X_OTP_MAGIC) &&
- (ee->offset == 0) &&
- (ee->len == MAX_EEPROM_SIZE) &&
- (data[0] == OTP_INDICATOR_1))
- ret = lan743x_otp_write(adapter, ee->offset, ee->len, data);
+ if (adapter->flags & LAN743X_ADAPTER_FLAG_OTP) {
+ /* Beware! OTP is One Time Programming ONLY! */
+ if (ee->magic == LAN743X_OTP_MAGIC) {
+ ret = lan743x_otp_write(adapter, ee->offset,
+ ee->len, data);
+ }
+ } else {
+ if (ee->magic == LAN743X_EEPROM_MAGIC) {
+ ret = lan743x_eeprom_write(adapter, ee->offset,
+ ee->len, data);
+ }
+ }
return ret;
}
@@ -360,6 +455,10 @@ static const u32 lan743x_set2_hw_cnt_addr[] = {
STAT_TX_COUNTER_ROLLOVER_STATUS
};
+static const char lan743x_priv_flags_strings[][ETH_GSTRING_LEN] = {
+ "OTP_ACCESS",
+};
+
static void lan743x_ethtool_get_strings(struct net_device *netdev,
u32 stringset, u8 *data)
{
@@ -375,6 +474,10 @@ static void lan743x_ethtool_get_strings(struct net_device *netdev,
lan743x_set2_hw_cnt_strings,
sizeof(lan743x_set2_hw_cnt_strings));
break;
+ case ETH_SS_PRIV_FLAGS:
+ memcpy(data, lan743x_priv_flags_strings,
+ sizeof(lan743x_priv_flags_strings));
+ break;
}
}
@@ -399,6 +502,22 @@ static void lan743x_ethtool_get_ethtool_stats(struct net_device *netdev,
}
}
+static u32 lan743x_ethtool_get_priv_flags(struct net_device *netdev)
+{
+ struct lan743x_adapter *adapter = netdev_priv(netdev);
+
+ return adapter->flags;
+}
+
+static int lan743x_ethtool_set_priv_flags(struct net_device *netdev, u32 flags)
+{
+ struct lan743x_adapter *adapter = netdev_priv(netdev);
+
+ adapter->flags = flags;
+
+ return 0;
+}
+
static int lan743x_ethtool_get_sset_count(struct net_device *netdev, int sset)
{
switch (sset) {
@@ -411,6 +530,8 @@ static int lan743x_ethtool_get_sset_count(struct net_device *netdev, int sset)
ret += ARRAY_SIZE(lan743x_set2_hw_cnt_strings);
return ret;
}
+ case ETH_SS_PRIV_FLAGS:
+ return ARRAY_SIZE(lan743x_priv_flags_strings);
default:
return -EOPNOTSUPP;
}
@@ -705,6 +826,8 @@ const struct ethtool_ops lan743x_ethtool_ops = {
.set_eeprom = lan743x_ethtool_set_eeprom,
.get_strings = lan743x_ethtool_get_strings,
.get_ethtool_stats = lan743x_ethtool_get_ethtool_stats,
+ .get_priv_flags = lan743x_ethtool_get_priv_flags,
+ .set_priv_flags = lan743x_ethtool_set_priv_flags,
.get_sset_count = lan743x_ethtool_get_sset_count,
.get_rxnfc = lan743x_ethtool_get_rxnfc,
.get_rxfh_key_size = lan743x_ethtool_get_rxfh_key_size,
diff --git a/drivers/net/ethernet/microchip/lan743x_main.h b/drivers/net/ethernet/microchip/lan743x_main.h
index 2d6eea1..3b02eea 100644
--- a/drivers/net/ethernet/microchip/lan743x_main.h
+++ b/drivers/net/ethernet/microchip/lan743x_main.h
@@ -26,6 +26,8 @@
#define FPGA_REV_GET_MAJOR_(fpga_rev) ((fpga_rev) & 0x000000FF)
#define HW_CFG (0x010)
+#define HW_CFG_RELOAD_TYPE_ALL_ (0x00000FC0)
+#define HW_CFG_EE_OTP_RELOAD_ BIT(4)
#define HW_CFG_LRST_ BIT(1)
#define PMT_CTL (0x014)
@@ -453,17 +455,19 @@
#define OTP_PWR_DN (0x1000)
#define OTP_PWR_DN_PWRDN_N_ BIT(0)
-#define OTP_ADDR1 (0x1004)
-#define OTP_ADDR1_15_11_MASK_ (0x1F)
-
-#define OTP_ADDR2 (0x1008)
-#define OTP_ADDR2_10_3_MASK_ (0xFF)
+#define OTP_ADDR_HIGH (0x1004)
+#define OTP_ADDR_LOW (0x1008)
#define OTP_PRGM_DATA (0x1010)
#define OTP_PRGM_MODE (0x1014)
#define OTP_PRGM_MODE_BYTE_ BIT(0)
+#define OTP_READ_DATA (0x1018)
+
+#define OTP_FUNC_CMD (0x1020)
+#define OTP_FUNC_CMD_READ_ BIT(0)
+
#define OTP_TST_CMD (0x1024)
#define OTP_TST_CMD_PRGVRFY_ BIT(3)
@@ -713,6 +717,9 @@ struct lan743x_adapter {
struct lan743x_phy phy;
struct lan743x_tx tx[LAN743X_MAX_TX_CHANNELS];
struct lan743x_rx rx[LAN743X_MAX_RX_CHANNELS];
+
+#define LAN743X_ADAPTER_FLAG_OTP BIT(0)
+ u32 flags;
};
#define LAN743X_COMPONENT_FLAG_RX(channel) BIT(20 + (channel))
--
2.7.4
^ permalink raw reply related
* Re: [PATCH net-next 06/10] net: introduce a net_device_ops macsec helper
From: Florian Fainelli @ 2019-01-23 20:16 UTC (permalink / raw)
To: Antoine Tenart, davem, sd, andrew, hkallweit1
Cc: netdev, linux-kernel, thomas.petazzoni, alexandre.belloni,
quentin.schulz, allan.nielsen
In-Reply-To: <20190123155638.13852-7-antoine.tenart@bootlin.com>
On 1/23/19 7:56 AM, Antoine Tenart wrote:
> This patch introduces a net_device_ops MACsec helper to allow net device
> drivers to implement a MACsec offloading solution.
>
> Signed-off-by: Antoine Tenart <antoine.tenart@bootlin.com>
> ---
> include/linux/netdevice.h | 8 ++++++++
> 1 file changed, 8 insertions(+)
>
> diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
> index e675ef97a426..ee2f40dca515 100644
> --- a/include/linux/netdevice.h
> +++ b/include/linux/netdevice.h
> @@ -53,6 +53,10 @@
> #include <uapi/linux/pkt_cls.h>
> #include <linux/hashtable.h>
>
> +#ifdef CONFIG_MACSEC
> +#include <net/macsec.h>
> +#endif
You can provide a forward declaration for struct netdev_macsec and not
have to include that header file.
> +
> struct netpoll_info;
> struct device;
> struct phy_device;
> @@ -1441,6 +1445,10 @@ struct net_device_ops {
> u32 flags);
> int (*ndo_xsk_async_xmit)(struct net_device *dev,
> u32 queue_id);
> +#ifdef CONFIG_MACSEC
> + int (*ndo_macsec)(struct net_device *dev,
> + struct netdev_macsec *macsec);
You would really want to define an API which is more oriented towards
configuring/deconfiguring a MACsec association here, e.g.: similar to
what the IPsec offload ndos offer.
It is not clear to me whether after your patch series we still need to
create a macsec virtual device, and that gets offloaded onto its real
device/PHY device, or if we don't need that all?
--
Florian
^ permalink raw reply
* Re: [PATCH net-next 03/10] net: macsec: move some definitions in a dedicated header
From: Florian Fainelli @ 2019-01-23 20:11 UTC (permalink / raw)
To: Antoine Tenart, davem, sd, andrew, hkallweit1
Cc: netdev, linux-kernel, thomas.petazzoni, alexandre.belloni,
quentin.schulz, allan.nielsen
In-Reply-To: <20190123155638.13852-4-antoine.tenart@bootlin.com>
On 1/23/19 7:56 AM, Antoine Tenart wrote:
> This patch moves some structure, type and identifier definitions into a
> MACsec specific header. This patch does not modify how the MACsec code
> is running and only move things around. This is a preparation for the
> future MACsec hardware offloading support, which will re-use those
> definitions outside macsec.c.
>
> Signed-off-by: Antoine Tenart <antoine.tenart@bootlin.com>
> ---
> drivers/net/macsec.c | 164 +--------------------------------------
> include/net/macsec.h | 178 +++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 179 insertions(+), 163 deletions(-)
> create mode 100644 include/net/macsec.h
>
> diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c
> index 56e354305f76..c3a138dd4386 100644
> --- a/drivers/net/macsec.c
> +++ b/drivers/net/macsec.c
> @@ -17,10 +17,9 @@
> #include <net/sock.h>
> #include <net/gro_cells.h>
>
> +#include <net/macsec.h>
> #include <uapi/linux/if_macsec.h>
I would probably go with include/linux/if_macsec.h and have
uapi/linux/if_macsec.h include that file directly. This would be
consistent with other types of network interfaces: bridge, vlan etc.
--
Florian
^ permalink raw reply
* [PATCH net-next 2/2] tcp_bbr: adapt cwnd based on ack aggregation estimation
From: Priyaranjan Jha @ 2019-01-23 20:04 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Priyaranjan Jha, Neal Cardwell, Yuchung Cheng
In-Reply-To: <20190123200454.260121-1-priyarjha@google.com>
Aggregation effects are extremely common with wifi, cellular, and cable
modem link technologies, ACK decimation in middleboxes, and LRO and GRO
in receiving hosts. The aggregation can happen in either direction,
data or ACKs, but in either case the aggregation effect is visible
to the sender in the ACK stream.
Previously BBR's sending was often limited by cwnd under severe ACK
aggregation/decimation because BBR sized the cwnd at 2*BDP. If packets
were acked in bursts after long delays (e.g. one ACK acking 5*BDP after
5*RTT), BBR's sending was halted after sending 2*BDP over 2*RTT, leaving
the bottleneck idle for potentially long periods. Note that loss-based
congestion control does not have this issue because when facing
aggregation it continues increasing cwnd after bursts of ACKs, growing
cwnd until the buffer is full.
To achieve good throughput in the presence of aggregation effects, this
algorithm allows the BBR sender to put extra data in flight to keep the
bottleneck utilized during silences in the ACK stream that it has evidence
to suggest were caused by aggregation.
A summary of the algorithm: when a burst of packets are acked by a
stretched ACK or a burst of ACKs or both, BBR first estimates the expected
amount of data that should have been acked, based on its estimated
bandwidth. Then the surplus ("extra_acked") is recorded in a windowed-max
filter to estimate the recent level of observed ACK aggregation. Then cwnd
is increased by the ACK aggregation estimate. The larger cwnd avoids BBR
being cwnd-limited in the face of ACK silences that recent history suggests
were caused by aggregation. As a sanity check, the ACK aggregation degree
is upper-bounded by the cwnd (at the time of measurement) and a global max
of BW * 100ms. The algorithm is further described by the following
presentation:
https://datatracker.ietf.org/meeting/101/materials/slides-101-iccrg-an-update-on-bbr-work-at-google-00
In our internal testing, we observed a significant increase in BBR
throughput (measured using netperf), in a basic wifi setup.
- Host1 (sender on ethernet) -> AP -> Host2 (receiver on wifi)
- 2.4 GHz -> BBR before: ~73 Mbps; BBR after: ~102 Mbps; CUBIC: ~100 Mbps
- 5.0 GHz -> BBR before: ~362 Mbps; BBR after: ~593 Mbps; CUBIC: ~601 Mbps
Also, this code is running globally on YouTube TCP connections and produced
significant bandwidth increases for YouTube traffic.
This is based on Ian Swett's max_ack_height_ algorithm from the
QUIC BBR implementation.
Signed-off-by: Priyaranjan Jha <priyarjha@google.com>
Signed-off-by: Neal Cardwell <ncardwell@google.com>
Signed-off-by: Yuchung Cheng <ycheng@google.com>
---
include/net/inet_connection_sock.h | 4 +-
net/ipv4/tcp_bbr.c | 122 ++++++++++++++++++++++++++++-
2 files changed, 123 insertions(+), 3 deletions(-)
diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h
index 371b3b45fd5c..fe0d9b44d6fc 100644
--- a/include/net/inet_connection_sock.h
+++ b/include/net/inet_connection_sock.h
@@ -139,8 +139,8 @@ struct inet_connection_sock {
} icsk_mtup;
u32 icsk_user_timeout;
- u64 icsk_ca_priv[88 / sizeof(u64)];
-#define ICSK_CA_PRIV_SIZE (11 * sizeof(u64))
+ u64 icsk_ca_priv[104 / sizeof(u64)];
+#define ICSK_CA_PRIV_SIZE (13 * sizeof(u64))
};
#define ICSK_TIME_RETRANS 1 /* Retransmit timer */
diff --git a/net/ipv4/tcp_bbr.c b/net/ipv4/tcp_bbr.c
index 6b6c7f14ccf9..56be7d27f208 100644
--- a/net/ipv4/tcp_bbr.c
+++ b/net/ipv4/tcp_bbr.c
@@ -115,6 +115,14 @@ struct bbr {
unused_b:5;
u32 prior_cwnd; /* prior cwnd upon entering loss recovery */
u32 full_bw; /* recent bw, to estimate if pipe is full */
+
+ /* For tracking ACK aggregation: */
+ u64 ack_epoch_mstamp; /* start of ACK sampling epoch */
+ u16 extra_acked[2]; /* max excess data ACKed in epoch */
+ u32 ack_epoch_acked:20, /* packets (S)ACKed in sampling epoch */
+ extra_acked_win_rtts:5, /* age of extra_acked, in round trips */
+ extra_acked_win_idx:1, /* current index in extra_acked array */
+ unused_c:6;
};
#define CYCLE_LEN 8 /* number of phases in a pacing gain cycle */
@@ -182,6 +190,15 @@ static const u32 bbr_lt_bw_diff = 4000 / 8;
/* If we estimate we're policed, use lt_bw for this many round trips: */
static const u32 bbr_lt_bw_max_rtts = 48;
+/* Gain factor for adding extra_acked to target cwnd: */
+static const int bbr_extra_acked_gain = BBR_UNIT;
+/* Window length of extra_acked window. */
+static const u32 bbr_extra_acked_win_rtts = 5;
+/* Max allowed val for ack_epoch_acked, after which sampling epoch is reset */
+static const u32 bbr_ack_epoch_acked_reset_thresh = 1U << 20;
+/* Time period for clamping cwnd increment due to ack aggregation */
+static const u32 bbr_extra_acked_max_us = 100 * 1000;
+
static void bbr_check_probe_rtt_done(struct sock *sk);
/* Do we estimate that STARTUP filled the pipe? */
@@ -208,6 +225,16 @@ static u32 bbr_bw(const struct sock *sk)
return bbr->lt_use_bw ? bbr->lt_bw : bbr_max_bw(sk);
}
+/* Return maximum extra acked in past k-2k round trips,
+ * where k = bbr_extra_acked_win_rtts.
+ */
+static u16 bbr_extra_acked(const struct sock *sk)
+{
+ struct bbr *bbr = inet_csk_ca(sk);
+
+ return max(bbr->extra_acked[0], bbr->extra_acked[1]);
+}
+
/* Return rate in bytes per second, optionally with a gain.
* The order here is chosen carefully to avoid overflow of u64. This should
* work for input rates of up to 2.9Tbit/sec and gain of 2.89x.
@@ -305,6 +332,8 @@ static void bbr_cwnd_event(struct sock *sk, enum tcp_ca_event event)
if (event == CA_EVENT_TX_START && tp->app_limited) {
bbr->idle_restart = 1;
+ bbr->ack_epoch_mstamp = tp->tcp_mstamp;
+ bbr->ack_epoch_acked = 0;
/* Avoid pointless buffer overflows: pace at est. bw if we don't
* need more speed (we're restarting from idle and app-limited).
*/
@@ -418,6 +447,22 @@ static u32 bbr_packets_in_net_at_edt(struct sock *sk, u32 inflight_now)
return inflight_at_edt - interval_delivered;
}
+/* Find the cwnd increment based on estimate of ack aggregation */
+static u32 bbr_ack_aggregation_cwnd(struct sock *sk)
+{
+ u32 max_aggr_cwnd, aggr_cwnd = 0;
+
+ if (bbr_extra_acked_gain && bbr_full_bw_reached(sk)) {
+ max_aggr_cwnd = ((u64)bbr_bw(sk) * bbr_extra_acked_max_us)
+ / BW_UNIT;
+ aggr_cwnd = (bbr_extra_acked_gain * bbr_extra_acked(sk))
+ >> BBR_SCALE;
+ aggr_cwnd = min(aggr_cwnd, max_aggr_cwnd);
+ }
+
+ return aggr_cwnd;
+}
+
/* An optimization in BBR to reduce losses: On the first round of recovery, we
* follow the packet conservation principle: send P packets per P packets acked.
* After that, we slow-start and send at most 2*P packets per P packets acked.
@@ -478,9 +523,15 @@ static void bbr_set_cwnd(struct sock *sk, const struct rate_sample *rs,
if (bbr_set_cwnd_to_recover_or_restore(sk, rs, acked, &cwnd))
goto done;
- /* If we're below target cwnd, slow start cwnd toward target cwnd. */
target_cwnd = bbr_bdp(sk, bw, gain);
+
+ /* Increment the cwnd to account for excess ACKed data that seems
+ * due to aggregation (of data and/or ACKs) visible in the ACK stream.
+ */
+ target_cwnd += bbr_ack_aggregation_cwnd(sk);
target_cwnd = bbr_quantization_budget(sk, target_cwnd, gain);
+
+ /* If we're below target cwnd, slow start cwnd toward target cwnd. */
if (bbr_full_bw_reached(sk)) /* only cut cwnd if we filled the pipe */
cwnd = min(cwnd + acked, target_cwnd);
else if (cwnd < target_cwnd || tp->delivered < TCP_INIT_CWND)
@@ -745,6 +796,67 @@ static void bbr_update_bw(struct sock *sk, const struct rate_sample *rs)
}
}
+/* Estimates the windowed max degree of ack aggregation.
+ * This is used to provision extra in-flight data to keep sending during
+ * inter-ACK silences.
+ *
+ * Degree of ack aggregation is estimated as extra data acked beyond expected.
+ *
+ * max_extra_acked = "maximum recent excess data ACKed beyond max_bw * interval"
+ * cwnd += max_extra_acked
+ *
+ * Max extra_acked is clamped by cwnd and bw * bbr_extra_acked_max_us (100 ms).
+ * Max filter is an approximate sliding window of 5-10 (packet timed) round
+ * trips.
+ */
+static void bbr_update_ack_aggregation(struct sock *sk,
+ const struct rate_sample *rs)
+{
+ u32 epoch_us, expected_acked, extra_acked;
+ struct bbr *bbr = inet_csk_ca(sk);
+ struct tcp_sock *tp = tcp_sk(sk);
+
+ if (!bbr_extra_acked_gain || rs->acked_sacked <= 0 ||
+ rs->delivered < 0 || rs->interval_us <= 0)
+ return;
+
+ if (bbr->round_start) {
+ bbr->extra_acked_win_rtts = min(0x1F,
+ bbr->extra_acked_win_rtts + 1);
+ if (bbr->extra_acked_win_rtts >= bbr_extra_acked_win_rtts) {
+ bbr->extra_acked_win_rtts = 0;
+ bbr->extra_acked_win_idx = bbr->extra_acked_win_idx ?
+ 0 : 1;
+ bbr->extra_acked[bbr->extra_acked_win_idx] = 0;
+ }
+ }
+
+ /* Compute how many packets we expected to be delivered over epoch. */
+ epoch_us = tcp_stamp_us_delta(tp->delivered_mstamp,
+ bbr->ack_epoch_mstamp);
+ expected_acked = ((u64)bbr_bw(sk) * epoch_us) / BW_UNIT;
+
+ /* Reset the aggregation epoch if ACK rate is below expected rate or
+ * significantly large no. of ack received since epoch (potentially
+ * quite old epoch).
+ */
+ if (bbr->ack_epoch_acked <= expected_acked ||
+ (bbr->ack_epoch_acked + rs->acked_sacked >=
+ bbr_ack_epoch_acked_reset_thresh)) {
+ bbr->ack_epoch_acked = 0;
+ bbr->ack_epoch_mstamp = tp->delivered_mstamp;
+ expected_acked = 0;
+ }
+
+ /* Compute excess data delivered, beyond what was expected. */
+ bbr->ack_epoch_acked = min_t(u32, 0xFFFFF,
+ bbr->ack_epoch_acked + rs->acked_sacked);
+ extra_acked = bbr->ack_epoch_acked - expected_acked;
+ extra_acked = min(extra_acked, tp->snd_cwnd);
+ if (extra_acked > bbr->extra_acked[bbr->extra_acked_win_idx])
+ bbr->extra_acked[bbr->extra_acked_win_idx] = extra_acked;
+}
+
/* Estimate when the pipe is full, using the change in delivery rate: BBR
* estimates that STARTUP filled the pipe if the estimated bw hasn't changed by
* at least bbr_full_bw_thresh (25%) after bbr_full_bw_cnt (3) non-app-limited
@@ -899,6 +1011,7 @@ static void bbr_update_gains(struct sock *sk)
static void bbr_update_model(struct sock *sk, const struct rate_sample *rs)
{
bbr_update_bw(sk, rs);
+ bbr_update_ack_aggregation(sk, rs);
bbr_update_cycle_phase(sk, rs);
bbr_check_full_bw_reached(sk, rs);
bbr_check_drain(sk, rs);
@@ -950,6 +1063,13 @@ static void bbr_init(struct sock *sk)
bbr_reset_lt_bw_sampling(sk);
bbr_reset_startup_mode(sk);
+ bbr->ack_epoch_mstamp = tp->tcp_mstamp;
+ bbr->ack_epoch_acked = 0;
+ bbr->extra_acked_win_rtts = 0;
+ bbr->extra_acked_win_idx = 0;
+ bbr->extra_acked[0] = 0;
+ bbr->extra_acked[1] = 0;
+
cmpxchg(&sk->sk_pacing_status, SK_PACING_NONE, SK_PACING_NEEDED);
}
--
2.20.1.321.g9e740568ce-goog
^ permalink raw reply related
* [PATCH net-next 1/2] tcp_bbr: refactor bbr_target_cwnd() for general inflight provisioning
From: Priyaranjan Jha @ 2019-01-23 20:04 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Priyaranjan Jha, Neal Cardwell, Yuchung Cheng
In-Reply-To: <20190123200454.260121-1-priyarjha@google.com>
Because bbr_target_cwnd() is really a general-purpose BBR helper for
computing some volume of inflight data as a function of the estimated
BDP, refactor it into following helper functions:
- bbr_bdp()
- bbr_quantization_budget()
- bbr_inflight()
Signed-off-by: Priyaranjan Jha <priyarjha@google.com>
Signed-off-by: Neal Cardwell <ncardwell@google.com>
Signed-off-by: Yuchung Cheng <ycheng@google.com>
---
net/ipv4/tcp_bbr.c | 60 ++++++++++++++++++++++++++++++----------------
1 file changed, 39 insertions(+), 21 deletions(-)
diff --git a/net/ipv4/tcp_bbr.c b/net/ipv4/tcp_bbr.c
index 0f497fc49c3f..6b6c7f14ccf9 100644
--- a/net/ipv4/tcp_bbr.c
+++ b/net/ipv4/tcp_bbr.c
@@ -315,30 +315,19 @@ static void bbr_cwnd_event(struct sock *sk, enum tcp_ca_event event)
}
}
-/* Find target cwnd. Right-size the cwnd based on min RTT and the
- * estimated bottleneck bandwidth:
+/* Calculate bdp based on min RTT and the estimated bottleneck bandwidth:
*
- * cwnd = bw * min_rtt * gain = BDP * gain
+ * bdp = bw * min_rtt * gain
*
* The key factor, gain, controls the amount of queue. While a small gain
* builds a smaller queue, it becomes more vulnerable to noise in RTT
* measurements (e.g., delayed ACKs or other ACK compression effects). This
* noise may cause BBR to under-estimate the rate.
- *
- * To achieve full performance in high-speed paths, we budget enough cwnd to
- * fit full-sized skbs in-flight on both end hosts to fully utilize the path:
- * - one skb in sending host Qdisc,
- * - one skb in sending host TSO/GSO engine
- * - one skb being received by receiver host LRO/GRO/delayed-ACK engine
- * Don't worry, at low rates (bbr_min_tso_rate) this won't bloat cwnd because
- * in such cases tso_segs_goal is 1. The minimum cwnd is 4 packets,
- * which allows 2 outstanding 2-packet sequences, to try to keep pipe
- * full even with ACK-every-other-packet delayed ACKs.
*/
-static u32 bbr_target_cwnd(struct sock *sk, u32 bw, int gain)
+static u32 bbr_bdp(struct sock *sk, u32 bw, int gain)
{
struct bbr *bbr = inet_csk_ca(sk);
- u32 cwnd;
+ u32 bdp;
u64 w;
/* If we've never had a valid RTT sample, cap cwnd at the initial
@@ -353,7 +342,24 @@ static u32 bbr_target_cwnd(struct sock *sk, u32 bw, int gain)
w = (u64)bw * bbr->min_rtt_us;
/* Apply a gain to the given value, then remove the BW_SCALE shift. */
- cwnd = (((w * gain) >> BBR_SCALE) + BW_UNIT - 1) / BW_UNIT;
+ bdp = (((w * gain) >> BBR_SCALE) + BW_UNIT - 1) / BW_UNIT;
+
+ return bdp;
+}
+
+/* To achieve full performance in high-speed paths, we budget enough cwnd to
+ * fit full-sized skbs in-flight on both end hosts to fully utilize the path:
+ * - one skb in sending host Qdisc,
+ * - one skb in sending host TSO/GSO engine
+ * - one skb being received by receiver host LRO/GRO/delayed-ACK engine
+ * Don't worry, at low rates (bbr_min_tso_rate) this won't bloat cwnd because
+ * in such cases tso_segs_goal is 1. The minimum cwnd is 4 packets,
+ * which allows 2 outstanding 2-packet sequences, to try to keep pipe
+ * full even with ACK-every-other-packet delayed ACKs.
+ */
+static u32 bbr_quantization_budget(struct sock *sk, u32 cwnd, int gain)
+{
+ struct bbr *bbr = inet_csk_ca(sk);
/* Allow enough full-sized skbs in flight to utilize end systems. */
cwnd += 3 * bbr_tso_segs_goal(sk);
@@ -368,6 +374,17 @@ static u32 bbr_target_cwnd(struct sock *sk, u32 bw, int gain)
return cwnd;
}
+/* Find inflight based on min RTT and the estimated bottleneck bandwidth. */
+static u32 bbr_inflight(struct sock *sk, u32 bw, int gain)
+{
+ u32 inflight;
+
+ inflight = bbr_bdp(sk, bw, gain);
+ inflight = bbr_quantization_budget(sk, inflight, gain);
+
+ return inflight;
+}
+
/* With pacing at lower layers, there's often less data "in the network" than
* "in flight". With TSQ and departure time pacing at lower layers (e.g. fq),
* we often have several skbs queued in the pacing layer with a pre-scheduled
@@ -462,7 +479,8 @@ static void bbr_set_cwnd(struct sock *sk, const struct rate_sample *rs,
goto done;
/* If we're below target cwnd, slow start cwnd toward target cwnd. */
- target_cwnd = bbr_target_cwnd(sk, bw, gain);
+ target_cwnd = bbr_bdp(sk, bw, gain);
+ target_cwnd = bbr_quantization_budget(sk, target_cwnd, gain);
if (bbr_full_bw_reached(sk)) /* only cut cwnd if we filled the pipe */
cwnd = min(cwnd + acked, target_cwnd);
else if (cwnd < target_cwnd || tp->delivered < TCP_INIT_CWND)
@@ -503,14 +521,14 @@ static bool bbr_is_next_cycle_phase(struct sock *sk,
if (bbr->pacing_gain > BBR_UNIT)
return is_full_length &&
(rs->losses || /* perhaps pacing_gain*BDP won't fit */
- inflight >= bbr_target_cwnd(sk, bw, bbr->pacing_gain));
+ inflight >= bbr_inflight(sk, bw, bbr->pacing_gain));
/* A pacing_gain < 1.0 tries to drain extra queue we added if bw
* probing didn't find more bw. If inflight falls to match BDP then we
* estimate queue is drained; persisting would underutilize the pipe.
*/
return is_full_length ||
- inflight <= bbr_target_cwnd(sk, bw, BBR_UNIT);
+ inflight <= bbr_inflight(sk, bw, BBR_UNIT);
}
static void bbr_advance_cycle_phase(struct sock *sk)
@@ -762,11 +780,11 @@ static void bbr_check_drain(struct sock *sk, const struct rate_sample *rs)
if (bbr->mode == BBR_STARTUP && bbr_full_bw_reached(sk)) {
bbr->mode = BBR_DRAIN; /* drain queue we created */
tcp_sk(sk)->snd_ssthresh =
- bbr_target_cwnd(sk, bbr_max_bw(sk), BBR_UNIT);
+ bbr_inflight(sk, bbr_max_bw(sk), BBR_UNIT);
} /* fall through to check if in-flight is already small: */
if (bbr->mode == BBR_DRAIN &&
bbr_packets_in_net_at_edt(sk, tcp_packets_in_flight(tcp_sk(sk))) <=
- bbr_target_cwnd(sk, bbr_max_bw(sk), BBR_UNIT))
+ bbr_inflight(sk, bbr_max_bw(sk), BBR_UNIT))
bbr_reset_probe_bw_mode(sk); /* we estimate queue is drained */
}
--
2.20.1.321.g9e740568ce-goog
^ permalink raw reply related
* [PATCH net-next 0/2] tcp_bbr: Improving TCP BBR performance for WiFi and cellular networks
From: Priyaranjan Jha @ 2019-01-23 20:04 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Priyaranjan Jha
Ack aggregation is quite prevalent with wifi, cellular and cable modem
link tchnologies, ACK decimation in middleboxes, and common offloading
techniques such as TSO and GRO, at end hosts. Previously, BBR was often
cwnd-limited in the presence of severe ACK aggregation, which resulted in
low throughput due to insufficient data in flight.
To achieve good throughput for wifi and other paths with aggregation, this
patch series implements an ACK aggregation estimator for BBR, which
estimates the maximum recent degree of ACK aggregation and adapts cwnd
based on it. The algorithm is further described by the following
presentation:
https://datatracker.ietf.org/meeting/101/materials/slides-101-iccrg-an-update-on-bbr-work-at-google-00
(1) A preparatory patch, which refactors bbr_target_cwnd for generic
inflight provisioning.
(2) Implements BBR ack aggregation estimator and adapts cwnd based
on measured degree of ACK aggregation.
Priyaranjan Jha (2):
tcp_bbr: refactor bbr_target_cwnd() for general inflight provisioning
tcp_bbr: adapt cwnd based on ack aggregation estimation
include/net/inet_connection_sock.h | 4 +-
net/ipv4/tcp_bbr.c | 180 +++++++++++++++++++++++++----
2 files changed, 161 insertions(+), 23 deletions(-)
--
2.20.1.321.g9e740568ce-goog
^ permalink raw reply
* Re: general protection fault in nf_ct_gre_keymap_flush
From: syzbot @ 2019-01-23 19:49 UTC (permalink / raw)
To: coreteam, davem, fw, kadlec, linux-kernel, netdev,
netfilter-devel, pablo, syzkaller-bugs
In-Reply-To: <0000000000000cf22a058011d494@google.com>
syzbot has found a reproducer for the following crash on:
HEAD commit: 5b74ce505631 Add linux-next specific files for 20190123
git tree: linux-next
console output: https://syzkaller.appspot.com/x/log.txt?x=1137e1b7400000
kernel config: https://syzkaller.appspot.com/x/.config?x=d4d5d672c7c71240
dashboard link: https://syzkaller.appspot.com/bug?extid=fcee88b2d87f0539dfe9
compiler: gcc (GCC) 9.0.0 20181231 (experimental)
syz repro: https://syzkaller.appspot.com/x/repro.syz?x=165f80c0c00000
IMPORTANT: if you fix the bug, please add the following tag to the commit:
Reported-by: syzbot+fcee88b2d87f0539dfe9@syzkaller.appspotmail.com
kasan: CONFIG_KASAN_INLINE enabled
kasan: GPF could be caused by NULL-ptr deref or user memory access
general protection fault: 0000 [#1] PREEMPT SMP KASAN
CPU: 1 PID: 8342 Comm: syz-executor2 Not tainted 5.0.0-rc3-next-20190123 #18
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS
Google 01/01/2011
RIP: 0010:nf_ct_gre_keymap_flush+0xb9/0x2f0
net/netfilter/nf_conntrack_proto_gre.c:65
Code: 4c 89 f0 48 c1 e8 03 42 80 3c 20 00 0f 85 2b 02 00 00 4c 8b bb f8 16
00 00 48 b8 00 00 00 00 00 fc ff df 4c 89 f9 48 c1 e9 03 <80> 3c 01 00 0f
85 fc 01 00 00 4c 3b bd 68 ff ff ff 4d 8b 27 0f 84
RSP: 0018:ffff8880743eeef8 EFLAGS: 00010246
RAX: dffffc0000000000 RBX: ffff888074c10240 RCX: 0000000000000000
RDX: 1ffffffff146dff2 RSI: 0000000000000004 RDI: ffff8880743eee60
RBP: ffff8880743eefa8 R08: 1ffff1100e87ddcc R09: ffffed100e87ddcd
R10: ffffed100e87ddcc R11: 0000000000000003 R12: dffffc0000000000
R13: ffff8880743ef0b8 R14: ffff888074c11938 R15: 0000000000000000
FS: 00007f7ceb928700(0000) GS:ffff8880ae700000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000000020000000 CR3: 00000000a089b000 CR4: 00000000001406e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
Call Trace:
nf_conntrack_proto_pernet_fini+0x16/0x1a
net/netfilter/nf_conntrack_proto.c:617
nf_conntrack_cleanup_net_list+0x204/0x330
net/netfilter/nf_conntrack_core.c:2183
nf_conntrack_cleanup_net+0x1c5/0x270 net/netfilter/nf_conntrack_core.c:2156
nf_conntrack_pernet_init net/netfilter/nf_conntrack_standalone.c:1122
[inline]
nf_conntrack_pernet_init+0xc3f/0xf00
net/netfilter/nf_conntrack_standalone.c:1091
ops_init+0x109/0x5d0 net/core/net_namespace.c:129
setup_net+0x38f/0x940 net/core/net_namespace.c:314
copy_net_ns+0x2ae/0x4b0 net/core/net_namespace.c:437
create_new_namespaces+0x4ce/0x930 kernel/nsproxy.c:107
copy_namespaces+0x3ff/0x4d0 kernel/nsproxy.c:165
copy_process+0x4a2d/0x8890 kernel/fork.c:1920
_do_fork+0x1a9/0x1170 kernel/fork.c:2227
__do_sys_clone kernel/fork.c:2334 [inline]
__se_sys_clone kernel/fork.c:2328 [inline]
__x64_sys_clone+0xbf/0x150 kernel/fork.c:2328
do_syscall_64+0x1a3/0x800 arch/x86/entry/common.c:290
entry_SYSCALL_64_after_hwframe+0x49/0xbe
RIP: 0033:0x458099
Code: 6d b7 fb ff c3 66 2e 0f 1f 84 00 00 00 00 00 66 90 48 89 f8 48 89 f7
48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff
ff 0f 83 3b b7 fb ff c3 66 2e 0f 1f 84 00 00 00 00
RSP: 002b:00007f7ceb927c78 EFLAGS: 00000246 ORIG_RAX: 0000000000000038
RAX: ffffffffffffffda RBX: 0000000000000005 RCX: 0000000000458099
RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000070024103
RBP: 000000000073bfa0 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 00007f7ceb9286d4
R13: 00000000004be480 R14: 00000000004ce960 R15: 00000000ffffffff
Modules linked in:
---[ end trace cdb65ca986e98ff1 ]---
RIP: 0010:nf_ct_gre_keymap_flush+0xb9/0x2f0
net/netfilter/nf_conntrack_proto_gre.c:65
Code: 4c 89 f0 48 c1 e8 03 42 80 3c 20 00 0f 85 2b 02 00 00 4c 8b bb f8 16
00 00 48 b8 00 00 00 00 00 fc ff df 4c 89 f9 48 c1 e9 03 <80> 3c 01 00 0f
85 fc 01 00 00 4c 3b bd 68 ff ff ff 4d 8b 27 0f 84
RSP: 0018:ffff8880743eeef8 EFLAGS: 00010246
RAX: dffffc0000000000 RBX: ffff888074c10240 RCX: 0000000000000000
RDX: 1ffffffff146dff2 RSI: 0000000000000004 RDI: ffff8880743eee60
RBP: ffff8880743eefa8 R08: 1ffff1100e87ddcc R09: ffffed100e87ddcd
R10: ffffed100e87ddcc R11: 0000000000000003 R12: dffffc0000000000
R13: ffff8880743ef0b8 R14: ffff888074c11938 R15: 0000000000000000
FS: 00007f7ceb928700(0000) GS:ffff8880ae700000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000000020000000 CR3: 00000000a089b000 CR4: 00000000001406e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
^ permalink raw reply
* [PATCH net-next] r8169: factor out PHY init sequence adjusting 10M and ALDPS
From: Heiner Kallweit @ 2019-01-23 19:47 UTC (permalink / raw)
To: Realtek linux nic maintainers, David Miller; +Cc: netdev@vger.kernel.org
Few chip versions use the same sequence to adjust 10M and ALDPS, so
let's factor it out. This patch also fixes a (most likely) typo in
rtl8168g_1_hw_phy_config. There bit 8 in reg 0x14 on page 0x0bcc
was set and not cleared. According to the vendor driver this bit
needs to be cleared in all cases.
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
---
drivers/net/ethernet/realtek/r8169.c | 49 ++++++++++++----------------
1 file changed, 21 insertions(+), 28 deletions(-)
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
index 8666ec095..99fd5c1d7 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -3372,6 +3372,24 @@ static void rtl8168g_disable_aldps(struct rtl8169_private *tp)
phy_clear_bits(tp->phydev, 0x10, BIT(2));
}
+static void rtl8168g_phy_adjust_10m_aldps(struct rtl8169_private *tp)
+{
+ struct phy_device *phydev = tp->phydev;
+
+ phy_write(phydev, 0x1f, 0x0bcc);
+ phy_clear_bits(phydev, 0x14, BIT(8));
+
+ phy_write(phydev, 0x1f, 0x0a44);
+ phy_set_bits(phydev, 0x11, BIT(7) | BIT(6));
+
+ phy_write(phydev, 0x1f, 0x0a43);
+ phy_write(phydev, 0x13, 0x8084);
+ phy_clear_bits(phydev, 0x14, BIT(14) | BIT(13));
+ phy_set_bits(phydev, 0x10, BIT(12) | BIT(1) | BIT(0));
+
+ phy_write(phydev, 0x1f, 0x0000);
+}
+
static void rtl8168g_1_hw_phy_config(struct rtl8169_private *tp)
{
rtl_apply_firmware(tp);
@@ -3398,14 +3416,7 @@ static void rtl8168g_1_hw_phy_config(struct rtl8169_private *tp)
rtl_writephy(tp, 0x1f, 0x0a44);
rtl_w0w1_phy(tp, 0x11, 0x000c, 0x0000);
- rtl_writephy(tp, 0x1f, 0x0bcc);
- rtl_w0w1_phy(tp, 0x14, 0x0100, 0x0000);
- rtl_writephy(tp, 0x1f, 0x0a44);
- rtl_w0w1_phy(tp, 0x11, 0x00c0, 0x0000);
- rtl_writephy(tp, 0x1f, 0x0a43);
- rtl_writephy(tp, 0x13, 0x8084);
- rtl_w0w1_phy(tp, 0x14, 0x0000, 0x6000);
- rtl_w0w1_phy(tp, 0x10, 0x1003, 0x0000);
+ rtl8168g_phy_adjust_10m_aldps(tp);
/* EEE auto-fallback function */
rtl_writephy(tp, 0x1f, 0x0a4b);
@@ -3624,16 +3635,7 @@ static void rtl8168ep_1_hw_phy_config(struct rtl8169_private *tp)
rtl_w0w1_phy(tp, 0x11, 0x000c, 0x0000);
rtl_writephy(tp, 0x1f, 0x0000);
- /* patch 10M & ALDPS */
- rtl_writephy(tp, 0x1f, 0x0bcc);
- rtl_w0w1_phy(tp, 0x14, 0x0000, 0x0100);
- rtl_writephy(tp, 0x1f, 0x0a44);
- rtl_w0w1_phy(tp, 0x11, 0x00c0, 0x0000);
- rtl_writephy(tp, 0x1f, 0x0a43);
- rtl_writephy(tp, 0x13, 0x8084);
- rtl_w0w1_phy(tp, 0x14, 0x0000, 0x6000);
- rtl_w0w1_phy(tp, 0x10, 0x1003, 0x0000);
- rtl_writephy(tp, 0x1f, 0x0000);
+ rtl8168g_phy_adjust_10m_aldps(tp);
/* Enable EEE auto-fallback function */
rtl_writephy(tp, 0x1f, 0x0a4b);
@@ -3658,16 +3660,7 @@ static void rtl8168ep_1_hw_phy_config(struct rtl8169_private *tp)
static void rtl8168ep_2_hw_phy_config(struct rtl8169_private *tp)
{
- /* patch 10M & ALDPS */
- rtl_writephy(tp, 0x1f, 0x0bcc);
- rtl_w0w1_phy(tp, 0x14, 0x0000, 0x0100);
- rtl_writephy(tp, 0x1f, 0x0a44);
- rtl_w0w1_phy(tp, 0x11, 0x00c0, 0x0000);
- rtl_writephy(tp, 0x1f, 0x0a43);
- rtl_writephy(tp, 0x13, 0x8084);
- rtl_w0w1_phy(tp, 0x14, 0x0000, 0x6000);
- rtl_w0w1_phy(tp, 0x10, 0x1003, 0x0000);
- rtl_writephy(tp, 0x1f, 0x0000);
+ rtl8168g_phy_adjust_10m_aldps(tp);
/* Enable UC LPF tune function */
rtl_writephy(tp, 0x1f, 0x0a43);
--
2.20.1
^ permalink raw reply related
* [PATCH net-next] r8169: factor out disabling ALDPS
From: Heiner Kallweit @ 2019-01-23 19:39 UTC (permalink / raw)
To: Realtek linux nic maintainers, David Miller; +Cc: netdev@vger.kernel.org
Chip versions from RTL8168g onward use the same sequence to disable
ALDPS (Advanced Link-Down Power Saving). So let's factor this out.
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
---
drivers/net/ethernet/realtek/r8169.c | 31 ++++++++++------------------
1 file changed, 11 insertions(+), 20 deletions(-)
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
index f574b6b55..8666ec095 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -3366,6 +3366,12 @@ static void rtl8411_hw_phy_config(struct rtl8169_private *tp)
rtl_writephy(tp, 0x1f, 0x0000);
}
+static void rtl8168g_disable_aldps(struct rtl8169_private *tp)
+{
+ phy_write(tp->phydev, 0x1f, 0x0a43);
+ phy_clear_bits(tp->phydev, 0x10, BIT(2));
+}
+
static void rtl8168g_1_hw_phy_config(struct rtl8169_private *tp)
{
rtl_apply_firmware(tp);
@@ -3424,10 +3430,7 @@ static void rtl8168g_1_hw_phy_config(struct rtl8169_private *tp)
rtl_writephy(tp, 0x14, 0x9065);
rtl_writephy(tp, 0x14, 0x1065);
- /* Check ALDPS bit, disable it if enabled */
- rtl_writephy(tp, 0x1f, 0x0a43);
- if (rtl_readphy(tp, 0x10) & 0x0004)
- rtl_w0w1_phy(tp, 0x10, 0x0000, 0x0004);
+ rtl8168g_disable_aldps(tp);
rtl_writephy(tp, 0x1f, 0x0000);
}
@@ -3539,10 +3542,7 @@ static void rtl8168h_1_hw_phy_config(struct rtl8169_private *tp)
rtl_w0w1_phy(tp, 0x11, 0x0000, 0x0080);
rtl_writephy(tp, 0x1f, 0x0000);
- /* Check ALDPS bit, disable it if enabled */
- rtl_writephy(tp, 0x1f, 0x0a43);
- if (rtl_readphy(tp, 0x10) & 0x0004)
- rtl_w0w1_phy(tp, 0x10, 0x0000, 0x0004);
+ rtl8168g_disable_aldps(tp);
rtl_writephy(tp, 0x1f, 0x0000);
}
@@ -3612,10 +3612,7 @@ static void rtl8168h_2_hw_phy_config(struct rtl8169_private *tp)
rtl_w0w1_phy(tp, 0x11, 0x0000, 0x0080);
rtl_writephy(tp, 0x1f, 0x0000);
- /* Check ALDPS bit, disable it if enabled */
- rtl_writephy(tp, 0x1f, 0x0a43);
- if (rtl_readphy(tp, 0x10) & 0x0004)
- rtl_w0w1_phy(tp, 0x10, 0x0000, 0x0004);
+ rtl8168g_disable_aldps(tp);
rtl_writephy(tp, 0x1f, 0x0000);
}
@@ -3654,10 +3651,7 @@ static void rtl8168ep_1_hw_phy_config(struct rtl8169_private *tp)
rtl_w0w1_phy(tp, 0x11, 0x4000, 0x2000);
rtl_writephy(tp, 0x1f, 0x0000);
- /* Check ALDPS bit, disable it if enabled */
- rtl_writephy(tp, 0x1f, 0x0a43);
- if (rtl_readphy(tp, 0x10) & 0x0004)
- rtl_w0w1_phy(tp, 0x10, 0x0000, 0x0004);
+ rtl8168g_disable_aldps(tp);
rtl_writephy(tp, 0x1f, 0x0000);
}
@@ -3745,10 +3739,7 @@ static void rtl8168ep_2_hw_phy_config(struct rtl8169_private *tp)
rtl_writephy(tp, 0x14, 0x1065);
rtl_writephy(tp, 0x1f, 0x0000);
- /* Check ALDPS bit, disable it if enabled */
- rtl_writephy(tp, 0x1f, 0x0a43);
- if (rtl_readphy(tp, 0x10) & 0x0004)
- rtl_w0w1_phy(tp, 0x10, 0x0000, 0x0004);
+ rtl8168g_disable_aldps(tp);
rtl_writephy(tp, 0x1f, 0x0000);
}
--
2.20.1
^ permalink raw reply related
* Re: [PATCH net-next 2/5] exthdrs: Registration of TLV handlers and parameters
From: David Miller @ 2019-01-23 19:27 UTC (permalink / raw)
To: tom; +Cc: netdev, tom
In-Reply-To: <1548221483-3085-3-git-send-email-tom@quantonium.net>
From: Tom Herbert <tom@herbertland.com>
Date: Tue, 22 Jan 2019 21:31:20 -0800
> Define a table that contains 256 entries, one for each TLV. Each entry
> points to a structure that contains parameters and handler functions
> for receiving and transmitting TLVs. The receive and transmit properties
> can be managed independently.
A new 2K table of pointers, most of which are empty.
No, thank you.
^ permalink raw reply
* Re: [PATCH net-next] r8169: improve firmware handling
From: David Miller @ 2019-01-23 19:24 UTC (permalink / raw)
To: hkallweit1; +Cc: nic_swsd, netdev
In-Reply-To: <3e270780-6b3a-40e9-79f8-04068b2fe02b@gmail.com>
From: Heiner Kallweit <hkallweit1@gmail.com>
Date: Tue, 22 Jan 2019 22:23:41 +0100
> So far member rtl_fw has three states:
> - IS_ERR(rtl_fw): firmware not loaded
> - !rtl_fw: no firmware available
> - other: firmware loaded
>
> This can be made simpler and clearer by adding the firmware name as
> member fw_name to struct rtl8169_private. Then:
>
> - !fw_name: no firmware available
> - !rtl_fw: firmware not loaded
> - rtl_fw: firmware loaded
>
> This change also allows to easily merge rtl_request_uncached_firmware
> into rtl_request_firmware.
>
> Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Applied.
^ permalink raw reply
* Re: [PATCH net] ax25: fix possible use-after-free
From: David Miller @ 2019-01-23 19:18 UTC (permalink / raw)
To: edumazet; +Cc: netdev, eric.dumazet, ralf, syzkaller
In-Reply-To: <20190122184059.220252-1-edumazet@google.com>
From: Eric Dumazet <edumazet@google.com>
Date: Tue, 22 Jan 2019 10:40:59 -0800
> syzbot found that ax25 routes where not properly protected
> against concurrent use [1].
>
> In this particular report the bug happened while
> copying ax25->digipeat.
>
> Fix this problem by making sure we call ax25_get_route()
> while ax25_route_lock is held, so that no modification
> could happen while using the route.
>
> The current two ax25_get_route() callers do not sleep,
> so this change should be fine.
>
> Once we do that, ax25_get_route() no longer needs to
> grab a reference on the found route.
>
> [1]
...
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> Cc: Ralf Baechle <ralf@linux-mips.org>
> Reported-by: syzbot <syzkaller@googlegroups.com>
Applied.
^ 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