* [patch net-next] net: use ETHTOOL_FWVERS_LEN instead of ETHTOOL_BUSINFO_LEN for fw_ver strings
From: Jiri Pirko @ 2013-01-06 12:12 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA
Cc: davem-fT/PcQaiUtIeIZ0/mPfg9Q, linville-2XuSBdqkA4R54TAoqtyWWQ,
linux-wireless-u79uwXL29TY76Z2rM5mHXA
Signed-off-by: Jiri Pirko <jiri-rHqAuBHg3fBzbRFIqnYvSA@public.gmane.org>
---
drivers/net/wireless/ath/ath9k/htc_drv_init.c | 2 +-
drivers/net/wireless/iwlwifi/iwl-fw.h | 2 +-
drivers/net/wireless/ti/wlcore/wlcore_i.h | 4 ++--
include/net/cfg80211.h | 2 +-
4 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
index 05d5ba6..b2f85cb 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
@@ -783,7 +783,7 @@ static int ath9k_init_firmware_version(struct ath9k_htc_priv *priv)
priv->fw_version_major = be16_to_cpu(cmd_rsp.major);
priv->fw_version_minor = be16_to_cpu(cmd_rsp.minor);
- snprintf(hw->wiphy->fw_version, ETHTOOL_BUSINFO_LEN, "%d.%d",
+ snprintf(hw->wiphy->fw_version, sizeof(hw->wiphy->fw_version), "%d.%d",
priv->fw_version_major,
priv->fw_version_minor);
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw.h b/drivers/net/wireless/iwlwifi/iwl-fw.h
index d1a86b6..715291e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fw.h
@@ -157,7 +157,7 @@ struct fw_img {
struct iwl_fw {
u32 ucode_ver;
- char fw_version[ETHTOOL_BUSINFO_LEN];
+ char fw_version[ETHTOOL_FWVERS_LEN];
/* ucode images */
struct fw_img img[IWL_UCODE_TYPE_MAX];
diff --git a/drivers/net/wireless/ti/wlcore/wlcore_i.h b/drivers/net/wireless/ti/wlcore/wlcore_i.h
index 6678d4b..5ce26cf 100644
--- a/drivers/net/wireless/ti/wlcore/wlcore_i.h
+++ b/drivers/net/wireless/ti/wlcore/wlcore_i.h
@@ -122,9 +122,9 @@ enum {
struct wl1271_chip {
u32 id;
- char fw_ver_str[ETHTOOL_BUSINFO_LEN];
+ char fw_ver_str[ETHTOOL_FWVERS_LEN];
unsigned int fw_ver[NUM_FW_VER];
- char phy_fw_ver_str[ETHTOOL_BUSINFO_LEN];
+ char phy_fw_ver_str[ETHTOOL_FWVERS_LEN];
};
#define NUM_TX_QUEUES 4
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 8e6a6b7..f78fa19 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -2333,7 +2333,7 @@ struct wiphy {
u32 rts_threshold;
u8 coverage_class;
- char fw_version[ETHTOOL_BUSINFO_LEN];
+ char fw_version[ETHTOOL_FWVERS_LEN];
u32 hw_version;
#ifdef CONFIG_PM
--
1.8.1
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* Re: [3.8-rc] regression: NETDEV WATCHDOG: eth0 (r8169): transmit queue 0 timed out
From: Jörg Otte @ 2013-01-06 13:03 UTC (permalink / raw)
To: Francois Romieu; +Cc: Linux Kernel Mailing List, David S. Miller, netdev
In-Reply-To: <20130105165735.GB4906@electric-eye.fr.zoreil.com>
2013/1/5 Francois Romieu <romieu@fr.zoreil.com>:
> Can you check if things improve with v3.8-rc2 after removing :
>
> 1. 9ecb9aabaf634677c77af467f4e3028b09d7bcda
> r8169: workaround for missing extended GigaMAC registers
> 2. d64ec841517a25f6d468bde9f67e5b4cffdc67c7
> r8169: enable internal ASPM and clock request settings
Doesn't help for this problem.
However this fixes a second issue for me:
In 3.7.1 at startup the link came up after 15 sec.:
grep r8169 dmesg.3.7.1
[ 1.956842] r8169 Gigabit Ethernet driver 2.3LK-NAPI loaded
[ 1.957059] r8169 0000:02:00.0: irq 42 for MSI/MSI-X
[ 1.957161] r8169 0000:02:00.0 eth0: RTL8168evl/8111evl at..
[ 1.957163] r8169 0000:02:00.0 eth0: jumbo features [frames..
[ 13.575452] r8169 0000:02:00.0 eth0: link down
[ 13.575475] r8169 0000:02:00.0 eth0: link down
[ 15.181317] r8169 0000:02:00.0 eth0: link up
In 3.8rc the time increased to 24 seconds:
grep r8169 dmesg.3.8.0
[ 1.852546] r8169 Gigabit Ethernet driver 2.3LK-NAPI loaded
[ 1.852765] r8169 0000:02:00.0: irq 42 for MSI/MSI-X
[ 1.852872] r8169 0000:02:00.0 eth0: RTL8168evl/8111evl at...
[ 1.852874] r8169 0000:02:00.0 eth0: jumbo features [frames...
[ 14.150212] r8169 0000:02:00.0 eth0: link down
[ 14.150229] r8169 0000:02:00.0 eth0: link down
[ 24.140263] r8169 0000:02:00.0 eth0: link up
But with this revert I get the old performance:
dmesg | grep r8169
[ 1.816613] r8169 Gigabit Ethernet driver 2.3LK-NAPI loaded
[ 1.816832] r8169 0000:02:00.0: irq 42 for MSI/MSI-X
[ 1.816947] r8169 0000:02:00.0 eth0: RTL8168evl/8111evl at...
[ 1.816948] r8169 0000:02:00.0 eth0: jumbo features [frames...
[ 13.986401] r8169 0000:02:00.0 eth0: link down
[ 13.986422] r8169 0000:02:00.0 eth0: link down
[ 15.623631] r8169 0000:02:00.0 eth0: link up
Thus I recommend to revert this too.
> 3. e0c075577965d1c01b30038d38bf637b027a1df3
> r8169: enable ALDPS for power saving
That's it! This fixes the problem for me!
Thanks, Jörg
^ permalink raw reply
* Re: [PATCH V3 2/2] vhost: handle polling errors
From: Michael S. Tsirkin @ 2013-01-06 13:22 UTC (permalink / raw)
To: Jason Wang; +Cc: kvm, eric.dumazet, netdev, linux-kernel, virtualization, davem
In-Reply-To: <1357456718-3072-3-git-send-email-jasowang@redhat.com>
On Sun, Jan 06, 2013 at 03:18:38PM +0800, Jason Wang wrote:
> Polling errors were ignored by vhost/vhost_net, this may lead to crash when
> trying to remove vhost from waitqueue when after the polling is failed. Solve
> this problem by:
>
> - checking the poll->wqh before trying to remove from waitqueue
> - report an error when poll() returns a POLLERR in vhost_start_poll()
> - report an error when vhost_start_poll() fails in
> vhost_vring_ioctl()/vhost_net_set_backend() which is used to notify the
> failure to userspace.
> - report an error in the data path in vhost_net when meet polling errors.
>
> After those changes, we can safely drop the tx polling state in vhost_net since
> it was replaced by the checking of poll->wqh.
>
> Signed-off-by: Jason Wang <jasowang@redhat.com>
> ---
> drivers/vhost/net.c | 74 ++++++++++++++++--------------------------------
> drivers/vhost/vhost.c | 31 +++++++++++++++-----
> drivers/vhost/vhost.h | 2 +-
> 3 files changed, 49 insertions(+), 58 deletions(-)
>
> diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
> index d10ad6f..125c1e5 100644
> --- a/drivers/vhost/net.c
> +++ b/drivers/vhost/net.c
> @@ -64,20 +64,10 @@ enum {
> VHOST_NET_VQ_MAX = 2,
> };
>
> -enum vhost_net_poll_state {
> - VHOST_NET_POLL_DISABLED = 0,
> - VHOST_NET_POLL_STARTED = 1,
> - VHOST_NET_POLL_STOPPED = 2,
> -};
> -
> struct vhost_net {
> struct vhost_dev dev;
> struct vhost_virtqueue vqs[VHOST_NET_VQ_MAX];
> struct vhost_poll poll[VHOST_NET_VQ_MAX];
> - /* Tells us whether we are polling a socket for TX.
> - * We only do this when socket buffer fills up.
> - * Protected by tx vq lock. */
> - enum vhost_net_poll_state tx_poll_state;
> /* Number of TX recently submitted.
> * Protected by tx vq lock. */
> unsigned tx_packets;
> @@ -155,24 +145,6 @@ static void copy_iovec_hdr(const struct iovec *from, struct iovec *to,
> }
> }
>
> -/* Caller must have TX VQ lock */
> -static void tx_poll_stop(struct vhost_net *net)
> -{
> - if (likely(net->tx_poll_state != VHOST_NET_POLL_STARTED))
> - return;
> - vhost_poll_stop(net->poll + VHOST_NET_VQ_TX);
> - net->tx_poll_state = VHOST_NET_POLL_STOPPED;
> -}
> -
> -/* Caller must have TX VQ lock */
> -static void tx_poll_start(struct vhost_net *net, struct socket *sock)
> -{
> - if (unlikely(net->tx_poll_state != VHOST_NET_POLL_STOPPED))
> - return;
> - vhost_poll_start(net->poll + VHOST_NET_VQ_TX, sock->file);
> - net->tx_poll_state = VHOST_NET_POLL_STARTED;
> -}
> -
> /* In case of DMA done not in order in lower device driver for some reason.
> * upend_idx is used to track end of used idx, done_idx is used to track head
> * of used idx. Once lower device DMA done contiguously, we will signal KVM
> @@ -227,6 +199,7 @@ static void vhost_zerocopy_callback(struct ubuf_info *ubuf, bool success)
> static void handle_tx(struct vhost_net *net)
> {
> struct vhost_virtqueue *vq = &net->dev.vqs[VHOST_NET_VQ_TX];
> + struct vhost_poll *poll = net->poll + VHOST_NET_VQ_TX;
> unsigned out, in, s;
> int head;
> struct msghdr msg = {
> @@ -252,7 +225,8 @@ static void handle_tx(struct vhost_net *net)
> wmem = atomic_read(&sock->sk->sk_wmem_alloc);
> if (wmem >= sock->sk->sk_sndbuf) {
> mutex_lock(&vq->mutex);
> - tx_poll_start(net, sock);
> + if (vhost_poll_start(poll, sock->file))
> + vq_err(vq, "Fail to start TX polling\n");
s/Fail/Failed/
A question though: how can this happen? Could you clarify please?
Maybe we can find a way to prevent this error?
> mutex_unlock(&vq->mutex);
> return;
> }
> @@ -261,7 +235,7 @@ static void handle_tx(struct vhost_net *net)
> vhost_disable_notify(&net->dev, vq);
>
> if (wmem < sock->sk->sk_sndbuf / 2)
> - tx_poll_stop(net);
> + vhost_poll_stop(poll);
> hdr_size = vq->vhost_hlen;
> zcopy = vq->ubufs;
>
> @@ -283,8 +257,10 @@ static void handle_tx(struct vhost_net *net)
>
> wmem = atomic_read(&sock->sk->sk_wmem_alloc);
> if (wmem >= sock->sk->sk_sndbuf * 3 / 4) {
> - tx_poll_start(net, sock);
> - set_bit(SOCK_ASYNC_NOSPACE, &sock->flags);
> + if (vhost_poll_start(poll, sock->file))
> + vq_err(vq, "Fail to start TX polling\n");
> + else
> + set_bit(SOCK_ASYNC_NOSPACE, &sock->flags);
> break;
> }
> /* If more outstanding DMAs, queue the work.
> @@ -294,8 +270,10 @@ static void handle_tx(struct vhost_net *net)
> (vq->upend_idx - vq->done_idx) :
> (vq->upend_idx + UIO_MAXIOV - vq->done_idx);
> if (unlikely(num_pends > VHOST_MAX_PEND)) {
> - tx_poll_start(net, sock);
> - set_bit(SOCK_ASYNC_NOSPACE, &sock->flags);
> + if (vhost_poll_start(poll, sock->file))
> + vq_err(vq, "Fail to start TX polling\n");
> + else
> + set_bit(SOCK_ASYNC_NOSPACE, &sock->flags);
> break;
> }
> if (unlikely(vhost_enable_notify(&net->dev, vq))) {
> @@ -360,7 +338,8 @@ static void handle_tx(struct vhost_net *net)
> }
> vhost_discard_vq_desc(vq, 1);
> if (err == -EAGAIN || err == -ENOBUFS)
> - tx_poll_start(net, sock);
> + if (vhost_poll_start(poll, sock->file))
> + vq_err(vq, "Fail to start TX polling\n");
> break;
> }
> if (err != len)
> @@ -623,7 +602,6 @@ static int vhost_net_open(struct inode *inode, struct file *f)
>
> vhost_poll_init(n->poll + VHOST_NET_VQ_TX, handle_tx_net, POLLOUT, dev);
> vhost_poll_init(n->poll + VHOST_NET_VQ_RX, handle_rx_net, POLLIN, dev);
> - n->tx_poll_state = VHOST_NET_POLL_DISABLED;
>
> f->private_data = n;
>
> @@ -633,29 +611,25 @@ static int vhost_net_open(struct inode *inode, struct file *f)
> static void vhost_net_disable_vq(struct vhost_net *n,
> struct vhost_virtqueue *vq)
> {
> + struct vhost_poll *poll = n->poll + (vq - n->vqs);
> +
> if (!vq->private_data)
> return;
> - if (vq == n->vqs + VHOST_NET_VQ_TX) {
> - tx_poll_stop(n);
> - n->tx_poll_state = VHOST_NET_POLL_DISABLED;
> - } else
> - vhost_poll_stop(n->poll + VHOST_NET_VQ_RX);
> + vhost_poll_stop(poll);
> }
>
> -static void vhost_net_enable_vq(struct vhost_net *n,
> +static int vhost_net_enable_vq(struct vhost_net *n,
> struct vhost_virtqueue *vq)
> {
> struct socket *sock;
> + struct vhost_poll *poll = n->poll + (vq - n->vqs);
>
> sock = rcu_dereference_protected(vq->private_data,
> lockdep_is_held(&vq->mutex));
> if (!sock)
> - return;
> - if (vq == n->vqs + VHOST_NET_VQ_TX) {
> - n->tx_poll_state = VHOST_NET_POLL_STOPPED;
> - tx_poll_start(n, sock);
> - } else
> - vhost_poll_start(n->poll + VHOST_NET_VQ_RX, sock->file);
> + return 0;
> +
> + return vhost_poll_start(poll, sock->file);
> }
>
> static struct socket *vhost_net_stop_vq(struct vhost_net *n,
> @@ -833,7 +807,9 @@ static long vhost_net_set_backend(struct vhost_net *n, unsigned index, int fd)
> r = vhost_init_used(vq);
> if (r)
> goto err_used;
> - vhost_net_enable_vq(n, vq);
> + r = vhost_net_enable_vq(n, vq);
> + if (r)
> + goto err_used;
>
> oldubufs = vq->ubufs;
> vq->ubufs = ubufs;
> diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
> index 34389f7..5c7a466 100644
> --- a/drivers/vhost/vhost.c
> +++ b/drivers/vhost/vhost.c
> @@ -77,26 +77,41 @@ void vhost_poll_init(struct vhost_poll *poll, vhost_work_fn_t fn,
> init_poll_funcptr(&poll->table, vhost_poll_func);
> poll->mask = mask;
> poll->dev = dev;
> + poll->wqh = NULL;
>
> vhost_work_init(&poll->work, fn);
> }
>
> +/* Stop polling a file. After this function returns, it becomes safe to drop the
> + * file reference. You must also flush afterwards. */
> +void vhost_poll_stop(struct vhost_poll *poll)
> +{
> + if (poll->wqh) {
> + remove_wait_queue(poll->wqh, &poll->wait);
> + poll->wqh = NULL;
> + }
> +}
> +
> /* Start polling a file. We add ourselves to file's wait queue. The caller must
> * keep a reference to a file until after vhost_poll_stop is called. */
> -void vhost_poll_start(struct vhost_poll *poll, struct file *file)
> +int vhost_poll_start(struct vhost_poll *poll, struct file *file)
> {
> unsigned long mask;
> + int ret = 0;
> +
> + if (poll->wqh)
> + return -EBUSY;
>
I think this should return success: we are already polling.
Otherwise this would trigger a bug below I think.
> mask = file->f_op->poll(file, &poll->table);
> if (mask)
> vhost_poll_wakeup(&poll->wait, 0, 0, (void *)mask);
> -}
>
> -/* Stop polling a file. After this function returns, it becomes safe to drop the
> - * file reference. You must also flush afterwards. */
> -void vhost_poll_stop(struct vhost_poll *poll)
> -{
> - remove_wait_queue(poll->wqh, &poll->wait);
> + if (mask & POLLERR) {
> + ret = -EINVAL;
> + vhost_poll_stop(poll);
> + }
> +
> + return ret;
> }
>
> static bool vhost_work_seq_done(struct vhost_dev *dev, struct vhost_work *work,
> @@ -792,7 +807,7 @@ long vhost_vring_ioctl(struct vhost_dev *d, int ioctl, void __user *argp)
> fput(filep);
>
> if (pollstart && vq->handle_kick)
> - vhost_poll_start(&vq->poll, vq->kick);
> + r = vhost_poll_start(&vq->poll, vq->kick);
>
> mutex_unlock(&vq->mutex);
>
> diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h
> index 2639c58..17261e2 100644
> --- a/drivers/vhost/vhost.h
> +++ b/drivers/vhost/vhost.h
> @@ -42,7 +42,7 @@ void vhost_work_queue(struct vhost_dev *dev, struct vhost_work *work);
>
> void vhost_poll_init(struct vhost_poll *poll, vhost_work_fn_t fn,
> unsigned long mask, struct vhost_dev *dev);
> -void vhost_poll_start(struct vhost_poll *poll, struct file *file);
> +int vhost_poll_start(struct vhost_poll *poll, struct file *file);
> void vhost_poll_stop(struct vhost_poll *poll);
> void vhost_poll_flush(struct vhost_poll *poll);
> void vhost_poll_queue(struct vhost_poll *poll);
> --
> 1.7.1
^ permalink raw reply
* [patch net] ethoc: fix mac address set
From: Jiri Pirko @ 2013-01-06 13:25 UTC (permalink / raw)
To: netdev; +Cc: davem
Function ethoc_set_mac_address() was incorrectly using passed pointer as
pointer to address, that is not correct.
Struct sockaddr have to be be used here.
Signed-off-by: Jiri Pirko <jiri@resnulli.us>
---
drivers/net/ethernet/ethoc.c | 22 +++++++++++-----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/drivers/net/ethernet/ethoc.c b/drivers/net/ethernet/ethoc.c
index b93062d..b51c81a 100644
--- a/drivers/net/ethernet/ethoc.c
+++ b/drivers/net/ethernet/ethoc.c
@@ -771,20 +771,24 @@ static int ethoc_config(struct net_device *dev, struct ifmap *map)
return -ENOSYS;
}
-static int ethoc_set_mac_address(struct net_device *dev, void *addr)
+static void ethoc_do_set_mac_address(struct net_device *dev)
{
struct ethoc *priv = netdev_priv(dev);
- u8 *mac = (u8 *)addr;
-
- if (!is_valid_ether_addr(mac))
- return -EADDRNOTAVAIL;
+ unsigned char *mac = dev->dev_addr;
ethoc_write(priv, MAC_ADDR0, (mac[2] << 24) | (mac[3] << 16) |
(mac[4] << 8) | (mac[5] << 0));
ethoc_write(priv, MAC_ADDR1, (mac[0] << 8) | (mac[1] << 0));
+}
- memcpy(dev->dev_addr, mac, ETH_ALEN);
+static int ethoc_set_mac_address(struct net_device *dev, void *p)
+{
+ const struct sockaddr *addr = p;
+ if (!is_valid_ether_addr(addr->sa_data))
+ return -EADDRNOTAVAIL;
+ memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
+ ethoc_do_set_mac_address(dev);
return 0;
}
@@ -1060,11 +1064,7 @@ static int ethoc_probe(struct platform_device *pdev)
random_mac = true;
}
- ret = ethoc_set_mac_address(netdev, netdev->dev_addr);
- if (ret) {
- dev_err(&netdev->dev, "failed to set MAC address\n");
- goto error;
- }
+ ethoc_do_set_mac_address(netdev);
if (random_mac)
netdev->addr_assign_type = NET_ADDR_RANDOM;
--
1.8.1
^ permalink raw reply related
* Re: Major network performance regression in 3.7
From: Eric Dumazet @ 2013-01-06 14:59 UTC (permalink / raw)
To: Willy Tarreau; +Cc: netdev, linux-kernel
In-Reply-To: <20130106092435.GZ16031@1wt.eu>
On Sun, 2013-01-06 at 10:24 +0100, Willy Tarreau wrote:
> It does not change anything to the tests above unfortunately. It did not
> even stabilize the unstable runs.
>
> I'll check if I can spot the original commit which caused the regression
> for MTUs that are not n*4096+52.
Since you don't post your program, I wont be able to help, just by
guessing what it does...
TCP has very low defaults concerning initial window, and it appears you
set RCVBUF to even smaller values.
Here we can see "win 8030", this is not a sane value...
18:32:08.071602 IP 127.0.0.1.26792 > 127.0.0.1.8000: S 2036886615:2036886615(0) win 8030 <mss 65495,nop,nop,sackOK,nop,wscale 9>
18:32:08.071605 IP 127.0.0.1.8000 > 127.0.0.1.26792: S 126397113:126397113(0) ack 2036886616 win 8030 <mss 65495,nop,nop,sackOK,nop,wscale 9>
So you apparently changed /proc/sys/net/ipv4/tcp_rmem or SO_RCVBUF ?
^ permalink raw reply
* Re: Major network performance regression in 3.7
From: Willy Tarreau @ 2013-01-06 15:51 UTC (permalink / raw)
To: Eric Dumazet; +Cc: netdev, linux-kernel
In-Reply-To: <1357484342.6919.61.camel@edumazet-glaptop>
Hi Eric,
On Sun, Jan 06, 2013 at 06:59:02AM -0800, Eric Dumazet wrote:
> On Sun, 2013-01-06 at 10:24 +0100, Willy Tarreau wrote:
>
> > It does not change anything to the tests above unfortunately. It did not
> > even stabilize the unstable runs.
> >
> > I'll check if I can spot the original commit which caused the regression
> > for MTUs that are not n*4096+52.
>
> Since you don't post your program, I wont be able to help, just by
> guessing what it does...
Oh sorry, I didn't really want to pollute the list with links and configs,
especially during the initial report with various combined issues :-(
The client is my old "inject" tool, available here :
http://git.1wt.eu/web?p=inject.git
The server is my "httpterm" tool, available here :
http://git.1wt.eu/web?p=httpterm.git
Use "-O3 -DENABLE_POLL -DENABLE_EPOLL -DENABLE_SPLICE" for CFLAGS.
I'm starting httpterm this way :
httpterm -D -L :8000 -P 256
=> it starts a server on port 8000, and sets pipe size to 256 kB. It
uses SPLICE_F_MORE on output data but removing it did not fix the
issue one of the early tests.
Then I'm starting inject this way :
inject -o 1 -u 1 -G 0:8000/?s=1g
=> 1 user, 1 object at a time, and fetch /?s=1g from the loopback.
The server will then emit 1 GB of data using splice().
It's possible to disable splicing on the server using -dS. The client
"eats" data using recv(MSG_TRUNC) to avoid a useless copy.
> TCP has very low defaults concerning initial window, and it appears you
> set RCVBUF to even smaller values.
Yes, you're right, my bootup scripts still change the default value, though
I increase them to larger values during the tests (except the one where you
saw win 8030 due to the default rmem set to 16060). I've been using this
value in the past with older kernels because it allowed an integer number
of segments to fit into the default window, and offered optimal performance
with large numbers of concurrent connections. Since 2.6, tcp_moderate_rcvbuf
works very well and this is not needed anymore.
Anyway, it does not affect the test here. Good kernels are OK whatever the
default value, and bad kernels are bad whatever the default value too.
Hmmm finally it's this commit again :
2f53384 tcp: allow splice() to build full TSO packets
I'm saying "again" because we already diagnosed a similar effect several
months ago that was revealed by this patch and we fixed it with the
following one, though I remember that we weren't completely sure it
would fix everything :
bad115c tcp: do_tcp_sendpages() must try to push data out on oom conditions
Just out of curiosity, I tried to re-apply the patch above just after the
first one but it did not change anything (after all it changed a symptom
which appeared in different conditions).
Interestingly, this commit (2f53384) significantly improved performance
on spliced data over the loopback (more than 50% in this test). In 3.7,
it seems to have no positive effect anymore. I reverted it using the
following patch and now the problem is fixed (mtu=64k works fine now) :
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index e457c7a..61e4517 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -935,7 +935,7 @@ wait_for_memory:
}
out:
- if (copied && !(flags & MSG_SENDPAGE_NOTLAST))
+ if (copied)
tcp_push(sk, flags, mss_now, tp->nonagle);
return copied;
Regards,
Willy
^ permalink raw reply related
* Re: Major network performance regression in 3.7
From: Eric Dumazet @ 2013-01-06 16:39 UTC (permalink / raw)
To: Willy Tarreau; +Cc: netdev, linux-kernel
In-Reply-To: <20130106155123.GB16031@1wt.eu>
On Sun, 2013-01-06 at 16:51 +0100, Willy Tarreau wrote:
> Hi Eric,
>
> Oh sorry, I didn't really want to pollute the list with links and configs,
> especially during the initial report with various combined issues :-(
>
> The client is my old "inject" tool, available here :
>
> http://git.1wt.eu/web?p=inject.git
>
> The server is my "httpterm" tool, available here :
>
> http://git.1wt.eu/web?p=httpterm.git
> Use "-O3 -DENABLE_POLL -DENABLE_EPOLL -DENABLE_SPLICE" for CFLAGS.
>
> I'm starting httpterm this way :
> httpterm -D -L :8000 -P 256
> => it starts a server on port 8000, and sets pipe size to 256 kB. It
> uses SPLICE_F_MORE on output data but removing it did not fix the
> issue one of the early tests.
>
> Then I'm starting inject this way :
> inject -o 1 -u 1 -G 0:8000/?s=1g
> => 1 user, 1 object at a time, and fetch /?s=1g from the loopback.
> The server will then emit 1 GB of data using splice().
>
> It's possible to disable splicing on the server using -dS. The client
> "eats" data using recv(MSG_TRUNC) to avoid a useless copy.
>
> > TCP has very low defaults concerning initial window, and it appears you
> > set RCVBUF to even smaller values.
>
> Yes, you're right, my bootup scripts still change the default value, though
> I increase them to larger values during the tests (except the one where you
> saw win 8030 due to the default rmem set to 16060). I've been using this
> value in the past with older kernels because it allowed an integer number
> of segments to fit into the default window, and offered optimal performance
> with large numbers of concurrent connections. Since 2.6, tcp_moderate_rcvbuf
> works very well and this is not needed anymore.
>
> Anyway, it does not affect the test here. Good kernels are OK whatever the
> default value, and bad kernels are bad whatever the default value too.
>
> Hmmm finally it's this commit again :
>
> 2f53384 tcp: allow splice() to build full TSO packets
>
> I'm saying "again" because we already diagnosed a similar effect several
> months ago that was revealed by this patch and we fixed it with the
> following one, though I remember that we weren't completely sure it
> would fix everything :
>
> bad115c tcp: do_tcp_sendpages() must try to push data out on oom conditions
>
> Just out of curiosity, I tried to re-apply the patch above just after the
> first one but it did not change anything (after all it changed a symptom
> which appeared in different conditions).
>
> Interestingly, this commit (2f53384) significantly improved performance
> on spliced data over the loopback (more than 50% in this test). In 3.7,
> it seems to have no positive effect anymore. I reverted it using the
> following patch and now the problem is fixed (mtu=64k works fine now) :
>
> diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
> index e457c7a..61e4517 100644
> --- a/net/ipv4/tcp.c
> +++ b/net/ipv4/tcp.c
> @@ -935,7 +935,7 @@ wait_for_memory:
> }
>
> out:
> - if (copied && !(flags & MSG_SENDPAGE_NOTLAST))
> + if (copied)
> tcp_push(sk, flags, mss_now, tp->nonagle);
> return copied;
>
> Regards,
> Willy
>
Hmm, I'll have to check if this really can be reverted without hurting
vmsplice() again.
^ permalink raw reply
* small iputils build patch
From: Arjan van de Ven @ 2013-01-06 16:42 UTC (permalink / raw)
To: netdev
[-- Attachment #1: Type: text/plain, Size: 404 bytes --]
The ping6 command can use either openssl or gnutls...
and the Makefile has a bunch of setup for defining which of the two to use.
Unfortunately, the final -D define on the commandline to enable gnutls
inside the ping6.c file didn't actually make it onto the gcc
commandline.
This patch adds the $(DEF_CRYPTO) Makefile variable to fix this gap.
Signed-off-by: Arjan van de Ven <arjanvandeven@gmail.com>
[-- Attachment #2: build.patch --]
[-- Type: application/octet-stream, Size: 962 bytes --]
The ping6 command can use either openssl or gnutls...
and the Makefile has a bunch of setup for defining which of the two to use.
Unfortunately, the final -D define on the commandline to enable gnutls inside the ping6.c file didn't actually make it onto the gcc commandline.
This patch adds the $(DEF_CRYPTO) Makefile variable to fix this gap.
Signed-off-by: Arjan van de Ven <arjanvandeven@gmail.com>
--- iputils-s20121221/Makefile~ 2012-12-21 06:01:07.000000000 -0800
+++ iputils-s20121221/Makefile 2013-01-06 08:27:56.014891846 -0800
@@ -149,7 +149,7 @@
DEF_ping_common = $(DEF_CAP) $(DEF_IDN)
DEF_ping = $(DEF_CAP) $(DEF_IDN) $(DEF_WITHOUT_IFADDRS)
LIB_ping = $(LIB_CAP) $(LIB_IDN)
-DEF_ping6 = $(DEF_CAP) $(DEF_IDN) $(DEF_WITHOUT_IFADDRS) $(DEF_ENABLE_PING6_RTHDR)
+DEF_ping6 = $(DEF_CAP) $(DEF_IDN) $(DEF_WITHOUT_IFADDRS) $(DEF_ENABLE_PING6_RTHDR) $(DEF_CRYPTO)
LIB_ping6 = $(LIB_CAP) $(LIB_IDN) $(LIB_RESOLV) $(LIB_CRYPTO)
ping: ping_common.o
^ permalink raw reply
* Re: Major network performance regression in 3.7
From: Willy Tarreau @ 2013-01-06 16:44 UTC (permalink / raw)
To: Eric Dumazet; +Cc: netdev, linux-kernel
In-Reply-To: <1357490393.6919.267.camel@edumazet-glaptop>
On Sun, Jan 06, 2013 at 08:39:53AM -0800, Eric Dumazet wrote:
> Hmm, I'll have to check if this really can be reverted without hurting
> vmsplice() again.
Looking at the code I've been wondering whether we shouldn't transform
the condition to perform the push if we can't push more segments, but
I don't know what to rely on. It would be something like this :
if (copied &&
(!(flags & MSG_SENDPAGE_NOTLAST) || cant_push_more))
tcp_push(sk, flags, mss_now, tp->nonagle);
Willy
^ permalink raw reply
* Re: Major network performance regression in 3.7
From: Eric Dumazet @ 2013-01-06 17:10 UTC (permalink / raw)
To: Willy Tarreau; +Cc: netdev, linux-kernel
In-Reply-To: <20130106164416.GF16031@1wt.eu>
On Sun, 2013-01-06 at 17:44 +0100, Willy Tarreau wrote:
> On Sun, Jan 06, 2013 at 08:39:53AM -0800, Eric Dumazet wrote:
> > Hmm, I'll have to check if this really can be reverted without hurting
> > vmsplice() again.
>
> Looking at the code I've been wondering whether we shouldn't transform
> the condition to perform the push if we can't push more segments, but
> I don't know what to rely on. It would be something like this :
>
> if (copied &&
> (!(flags & MSG_SENDPAGE_NOTLAST) || cant_push_more))
> tcp_push(sk, flags, mss_now, tp->nonagle);
Good point !
Maybe the following fix then ?
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 1ca2536..7ba0717 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -941,8 +941,10 @@ out:
return copied;
do_error:
- if (copied)
+ if (copied) {
+ flags &= ~MSG_SENDPAGE_NOTLAST;
goto out;
+ }
out_err:
return sk_stream_error(sk, flags, err);
}
^ permalink raw reply related
* Re: Major network performance regression in 3.7
From: Willy Tarreau @ 2013-01-06 17:35 UTC (permalink / raw)
To: Eric Dumazet; +Cc: netdev, linux-kernel
In-Reply-To: <1357492255.6919.336.camel@edumazet-glaptop>
On Sun, Jan 06, 2013 at 09:10:55AM -0800, Eric Dumazet wrote:
> On Sun, 2013-01-06 at 17:44 +0100, Willy Tarreau wrote:
> > On Sun, Jan 06, 2013 at 08:39:53AM -0800, Eric Dumazet wrote:
> > > Hmm, I'll have to check if this really can be reverted without hurting
> > > vmsplice() again.
> >
> > Looking at the code I've been wondering whether we shouldn't transform
> > the condition to perform the push if we can't push more segments, but
> > I don't know what to rely on. It would be something like this :
> >
> > if (copied &&
> > (!(flags & MSG_SENDPAGE_NOTLAST) || cant_push_more))
> > tcp_push(sk, flags, mss_now, tp->nonagle);
>
> Good point !
>
> Maybe the following fix then ?
>
>
> diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
> index 1ca2536..7ba0717 100644
> --- a/net/ipv4/tcp.c
> +++ b/net/ipv4/tcp.c
> @@ -941,8 +941,10 @@ out:
> return copied;
>
> do_error:
> - if (copied)
> + if (copied) {
> + flags &= ~MSG_SENDPAGE_NOTLAST;
> goto out;
> + }
> out_err:
> return sk_stream_error(sk, flags, err);
> }
Unfortunately it does not work any better, which means to me
that we don't leave via this code path. I tried other tricks
which failed too. I need to understand this part better before
randomly fiddling with it.
Willy
^ permalink raw reply
* Re: Major network performance regression in 3.7
From: Eric Dumazet @ 2013-01-06 18:39 UTC (permalink / raw)
To: Willy Tarreau; +Cc: netdev, linux-kernel
In-Reply-To: <20130106173543.GB22432@1wt.eu>
On Sun, 2013-01-06 at 18:35 +0100, Willy Tarreau wrote:
> Unfortunately it does not work any better, which means to me
> that we don't leave via this code path. I tried other tricks
> which failed too. I need to understand this part better before
> randomly fiddling with it.
>
OK, now I have your test program, I can work on a fix, dont worry ;)
The MSG_SENDPAGE_NOTLAST logic needs to be tweaked.
^ permalink raw reply
* Re: Major network performance regression in 3.7
From: Eric Dumazet @ 2013-01-06 18:43 UTC (permalink / raw)
To: Willy Tarreau; +Cc: netdev, linux-kernel
In-Reply-To: <1357497541.6919.519.camel@edumazet-glaptop>
On Sun, 2013-01-06 at 10:39 -0800, Eric Dumazet wrote:
> On Sun, 2013-01-06 at 18:35 +0100, Willy Tarreau wrote:
>
> > Unfortunately it does not work any better, which means to me
> > that we don't leave via this code path. I tried other tricks
> > which failed too. I need to understand this part better before
> > randomly fiddling with it.
> >
>
> OK, now I have your test program, I can work on a fix, dont worry ;)
>
> The MSG_SENDPAGE_NOTLAST logic needs to be tweaked.
>
(sd->len is usually 4096, which is expected, but sd->total_len value is
huge in your case, so we always set the flag in fs/splice.c)
^ permalink raw reply
* Re: Major network performance regression in 3.7
From: Eric Dumazet @ 2013-01-06 18:51 UTC (permalink / raw)
To: Willy Tarreau; +Cc: netdev, linux-kernel
In-Reply-To: <1357497809.6919.529.camel@edumazet-glaptop>
>
> (sd->len is usually 4096, which is expected, but sd->total_len value is
> huge in your case, so we always set the flag in fs/splice.c)
I am testing :
if (sd->len < sd->total_len && pipe->nrbufs > 1)
more |= MSG_SENDPAGE_NOTLAST;
^ permalink raw reply
* Re: Major network performance regression in 3.7
From: Eric Dumazet @ 2013-01-06 19:00 UTC (permalink / raw)
To: Willy Tarreau; +Cc: netdev, linux-kernel
In-Reply-To: <1357498276.6919.547.camel@edumazet-glaptop>
On Sun, 2013-01-06 at 10:51 -0800, Eric Dumazet wrote:
> >
> > (sd->len is usually 4096, which is expected, but sd->total_len value is
> > huge in your case, so we always set the flag in fs/splice.c)
>
> I am testing :
>
> if (sd->len < sd->total_len && pipe->nrbufs > 1)
> more |= MSG_SENDPAGE_NOTLAST;
>
Yes, this should fix the problem :
If there is no following buffer in the pipe, we should not set NOTLAST.
diff --git a/fs/splice.c b/fs/splice.c
index 8890604..6909d89 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -696,8 +696,10 @@ static int pipe_to_sendpage(struct pipe_inode_info *pipe,
return -EINVAL;
more = (sd->flags & SPLICE_F_MORE) ? MSG_MORE : 0;
- if (sd->len < sd->total_len)
+
+ if (sd->len < sd->total_len && pipe->nrbufs > 1)
more |= MSG_SENDPAGE_NOTLAST;
+
return file->f_op->sendpage(file, buf->page, buf->offset,
sd->len, &pos, more);
}
^ permalink raw reply related
* Re: Major network performance regression in 3.7
From: Willy Tarreau @ 2013-01-06 19:34 UTC (permalink / raw)
To: Eric Dumazet; +Cc: netdev, linux-kernel
In-Reply-To: <1357498815.6919.570.camel@edumazet-glaptop>
On Sun, Jan 06, 2013 at 11:00:15AM -0800, Eric Dumazet wrote:
> On Sun, 2013-01-06 at 10:51 -0800, Eric Dumazet wrote:
> > >
> > > (sd->len is usually 4096, which is expected, but sd->total_len value is
> > > huge in your case, so we always set the flag in fs/splice.c)
> >
> > I am testing :
> >
> > if (sd->len < sd->total_len && pipe->nrbufs > 1)
> > more |= MSG_SENDPAGE_NOTLAST;
> >
>
> Yes, this should fix the problem :
>
> If there is no following buffer in the pipe, we should not set NOTLAST.
>
> diff --git a/fs/splice.c b/fs/splice.c
> index 8890604..6909d89 100644
> --- a/fs/splice.c
> +++ b/fs/splice.c
> @@ -696,8 +696,10 @@ static int pipe_to_sendpage(struct pipe_inode_info *pipe,
> return -EINVAL;
>
> more = (sd->flags & SPLICE_F_MORE) ? MSG_MORE : 0;
> - if (sd->len < sd->total_len)
> +
> + if (sd->len < sd->total_len && pipe->nrbufs > 1)
> more |= MSG_SENDPAGE_NOTLAST;
> +
> return file->f_op->sendpage(file, buf->page, buf->offset,
> sd->len, &pos, more);
> }
OK it works like a charm here now ! I can't break it anymore, so it
looks like you finally got it !
I noticed that the data rate was higher when the loopback's MTU
is exactly a multiple of 4096 (making the 64k choice optimal)
while I would have assumed that in order to efficiently splice
TCP segments, we'd need to have some space for IP/TCP headers
and n*4k for the payload.
I also got the transfer freezes again a few times when starting
tcpdump on the server, but this is not 100% reproducible I'm afraid.
So I'll bring this back when I manage to get some analysable pattern.
The spliced transfer through all the chain haproxy works fine again
at 10gig with your fix. The issue is closed for me. Feel free to add
my Tested-By if you want.
Thank you Eric :-)
Willy
^ permalink raw reply
* Re: Major network performance regression in 3.7
From: Eric Dumazet @ 2013-01-06 19:39 UTC (permalink / raw)
To: Willy Tarreau; +Cc: netdev, linux-kernel
In-Reply-To: <20130106193410.GL16031@1wt.eu>
On Sun, 2013-01-06 at 20:34 +0100, Willy Tarreau wrote:
> OK it works like a charm here now ! I can't break it anymore, so it
> looks like you finally got it !
>
> I noticed that the data rate was higher when the loopback's MTU
> is exactly a multiple of 4096 (making the 64k choice optimal)
> while I would have assumed that in order to efficiently splice
> TCP segments, we'd need to have some space for IP/TCP headers
> and n*4k for the payload.
>
> I also got the transfer freezes again a few times when starting
> tcpdump on the server, but this is not 100% reproducible I'm afraid.
> So I'll bring this back when I manage to get some analysable pattern.
>
> The spliced transfer through all the chain haproxy works fine again
> at 10gig with your fix. The issue is closed for me. Feel free to add
> my Tested-By if you want.
>
Good to know !
What is the max speed you get now ?
^ permalink raw reply
* Re: Major network performance regression in 3.7
From: Willy Tarreau @ 2013-01-06 19:53 UTC (permalink / raw)
To: Eric Dumazet; +Cc: netdev, linux-kernel
In-Reply-To: <1357501171.6919.650.camel@edumazet-glaptop>
On Sun, Jan 06, 2013 at 11:39:31AM -0800, Eric Dumazet wrote:
> On Sun, 2013-01-06 at 20:34 +0100, Willy Tarreau wrote:
>
> > OK it works like a charm here now ! I can't break it anymore, so it
> > looks like you finally got it !
> >
> > I noticed that the data rate was higher when the loopback's MTU
> > is exactly a multiple of 4096 (making the 64k choice optimal)
> > while I would have assumed that in order to efficiently splice
> > TCP segments, we'd need to have some space for IP/TCP headers
> > and n*4k for the payload.
> >
> > I also got the transfer freezes again a few times when starting
> > tcpdump on the server, but this is not 100% reproducible I'm afraid.
> > So I'll bring this back when I manage to get some analysable pattern.
> >
> > The spliced transfer through all the chain haproxy works fine again
> > at 10gig with your fix. The issue is closed for me. Feel free to add
> > my Tested-By if you want.
> >
>
> Good to know !
>
> What is the max speed you get now ?
Line rate with 1500 MTU and LRO enabled :
# time eth1(ikb ipk okb opk) eth2(ikb ipk okb opk)
1357060023 19933.3 41527.7 9355538.2 62167.7 9757888.1 808701.1 19400.3 40417.7
1357060024 26124.1 54425.5 9290064.9 48804.4 9778294.0 810210.0 18068.8 37643.3
1357060025 27015.2 56281.1 9296115.3 46868.8 9797125.9 811271.1 8790.1 18312.2
1357060026 27556.0 57408.8 9291701.4 46805.5 9805371.6 811410.0 3494.8 7280.0
1357060027 27577.0 57452.2 9293606.8 46804.4 9806122.3 811314.4 2558.7 5330.0
1357060028 27476.1 57242.2 9296885.4 46830.0 9794537.3 810527.7 2516.1 5242.2
^^^^^^^ ^^^^^^^
kbps out kbps in
eth1=facing the client
eth2=facing the server
Top reports the following usage :
Cpu0 : 0.0%us, 0.0%sy, 0.0%ni, 31.7%id, 0.0%wa, 0.0%hi, 68.3%si, 0.0%st
Cpu1 : 1.0%us, 37.3%sy, 0.0%ni, 61.8%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
(IRQ bound to cpu 0, haproxy to cpu 1)
This is a core2duo 2.66 GHz and the myris are 1st generation.
BTW I was very happy to see that the LRO->GRO conversion patches in 3.8-rc2
don't affect byte rate anymore (just a minor CPU usage increase but this is
not critical here), now I won't complain about it being slower anymore, you
won :-)
With the GRO patches backported, still at 1500 MTU but with GRO now :
Cpu0 : 0.0%us, 0.0%sy, 0.0%ni, 28.7%id, 0.0%wa, 0.0%hi, 71.3%si, 0.0%st
Cpu1 : 0.0%us, 37.6%sy, 0.0%ni, 62.4%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
# time eth1(ikb ipk okb opk) eth2(ikb ipk okb opk)
1357058637 18319.3 38165.5 9401736.3 65159.9 9761613.4 808963.3 19403.6 40424.4
1357058638 20009.8 41687.7 9400903.7 62706.6 9770555.8 809522.2 18696.5 38951.1
1357058639 25439.5 52999.9 9301635.3 50267.7 9773666.7 809721.1 19174.1 39946.6
1357058640 26808.2 55850.0 9298301.4 46876.6 9790470.1 810843.3 12408.7 25851.1
1357058641 27110.9 56481.1 9297009.2 46832.2 9803308.4 811339.9 5692.5 11859.9
1357058642 27411.1 57106.6 9291419.2 46796.6 9806846.5 811378.8 2804.4 5842.2
This kernel is getting really good :-)
Cheers,
Willy
^ permalink raw reply
* Re: Major network performance regression in 3.7
From: John Stoffel @ 2013-01-06 21:49 UTC (permalink / raw)
To: Willy Tarreau; +Cc: Eric Dumazet, netdev, linux-kernel
In-Reply-To: <20130106193410.GL16031@1wt.eu>
>>>>> "Willy" == Willy Tarreau <w@1wt.eu> writes:
Willy> On Sun, Jan 06, 2013 at 11:00:15AM -0800, Eric Dumazet wrote:
>> On Sun, 2013-01-06 at 10:51 -0800, Eric Dumazet wrote:
>> > >
>> > > (sd->len is usually 4096, which is expected, but sd->total_len value is
>> > > huge in your case, so we always set the flag in fs/splice.c)
>> >
>> > I am testing :
>> >
>> > if (sd->len < sd->total_len && pipe->nrbufs > 1)
>> > more |= MSG_SENDPAGE_NOTLAST;
>> >
>>
>> Yes, this should fix the problem :
>>
>> If there is no following buffer in the pipe, we should not set NOTLAST.
>>
>> diff --git a/fs/splice.c b/fs/splice.c
>> index 8890604..6909d89 100644
>> --- a/fs/splice.c
>> +++ b/fs/splice.c
>> @@ -696,8 +696,10 @@ static int pipe_to_sendpage(struct pipe_inode_info *pipe,
>> return -EINVAL;
>>
>> more = (sd->flags & SPLICE_F_MORE) ? MSG_MORE : 0;
>> - if (sd->len < sd->total_len)
>> +
>> + if (sd->len < sd->total_len && pipe->nrbufs > 1)
>> more |= MSG_SENDPAGE_NOTLAST;
>> +
>> return file->f_op->sendpage(file, buf->page, buf->offset,
sd-> len, &pos, more);
>> }
Willy> OK it works like a charm here now ! I can't break it anymore, so it
Willy> looks like you finally got it !
It's still broken, there's no comments in the code to explain all this
magic to mere mortals! *grin*
John
^ permalink raw reply
* Re: Major network performance regression in 3.7
From: Willy Tarreau @ 2013-01-06 21:52 UTC (permalink / raw)
To: John Stoffel; +Cc: Eric Dumazet, netdev, linux-kernel
In-Reply-To: <20713.61807.385486.594545@quad.stoffel.home>
On Sun, Jan 06, 2013 at 04:49:35PM -0500, John Stoffel wrote:
> >>>>> "Willy" == Willy Tarreau <w@1wt.eu> writes:
>
> Willy> On Sun, Jan 06, 2013 at 11:00:15AM -0800, Eric Dumazet wrote:
> >> On Sun, 2013-01-06 at 10:51 -0800, Eric Dumazet wrote:
> >> > >
> >> > > (sd->len is usually 4096, which is expected, but sd->total_len value is
> >> > > huge in your case, so we always set the flag in fs/splice.c)
> >> >
> >> > I am testing :
> >> >
> >> > if (sd->len < sd->total_len && pipe->nrbufs > 1)
> >> > more |= MSG_SENDPAGE_NOTLAST;
> >> >
> >>
> >> Yes, this should fix the problem :
> >>
> >> If there is no following buffer in the pipe, we should not set NOTLAST.
> >>
> >> diff --git a/fs/splice.c b/fs/splice.c
> >> index 8890604..6909d89 100644
> >> --- a/fs/splice.c
> >> +++ b/fs/splice.c
> >> @@ -696,8 +696,10 @@ static int pipe_to_sendpage(struct pipe_inode_info *pipe,
> >> return -EINVAL;
> >>
> >> more = (sd->flags & SPLICE_F_MORE) ? MSG_MORE : 0;
> >> - if (sd->len < sd->total_len)
> >> +
> >> + if (sd->len < sd->total_len && pipe->nrbufs > 1)
> >> more |= MSG_SENDPAGE_NOTLAST;
> >> +
> >> return file->f_op->sendpage(file, buf->page, buf->offset,
> sd-> len, &pos, more);
> >> }
>
> Willy> OK it works like a charm here now ! I can't break it anymore, so it
> Willy> looks like you finally got it !
>
> It's still broken, there's no comments in the code to explain all this
> magic to mere mortals! *grin*
I would generally agree, but when Eric fixes such a thing, he
generally goes with lengthy details in the commit message.
Willy
^ permalink raw reply
* Re: Major network performance regression in 3.7
From: John Stoffel @ 2013-01-06 21:55 UTC (permalink / raw)
To: Willy Tarreau; +Cc: John Stoffel, Eric Dumazet, netdev, linux-kernel
In-Reply-To: <20130106215200.GV16031@1wt.eu>
>>>>> "Willy" == Willy Tarreau <w@1wt.eu> writes:
Willy> On Sun, Jan 06, 2013 at 04:49:35PM -0500, John Stoffel wrote:
>> >>>>> "Willy" == Willy Tarreau <w@1wt.eu> writes:
>>
Willy> On Sun, Jan 06, 2013 at 11:00:15AM -0800, Eric Dumazet wrote:
>> >> On Sun, 2013-01-06 at 10:51 -0800, Eric Dumazet wrote:
>> >> > >
>> >> > > (sd->len is usually 4096, which is expected, but sd->total_len value is
>> >> > > huge in your case, so we always set the flag in fs/splice.c)
>> >> >
>> >> > I am testing :
>> >> >
>> >> > if (sd->len < sd->total_len && pipe->nrbufs > 1)
>> >> > more |= MSG_SENDPAGE_NOTLAST;
>> >> >
>> >>
>> >> Yes, this should fix the problem :
>> >>
>> >> If there is no following buffer in the pipe, we should not set NOTLAST.
>> >>
>> >> diff --git a/fs/splice.c b/fs/splice.c
>> >> index 8890604..6909d89 100644
>> >> --- a/fs/splice.c
>> >> +++ b/fs/splice.c
>> >> @@ -696,8 +696,10 @@ static int pipe_to_sendpage(struct pipe_inode_info *pipe,
>> >> return -EINVAL;
>> >>
>> >> more = (sd->flags & SPLICE_F_MORE) ? MSG_MORE : 0;
>> >> - if (sd->len < sd->total_len)
>> >> +
>> >> + if (sd->len < sd->total_len && pipe->nrbufs > 1)
>> >> more |= MSG_SENDPAGE_NOTLAST;
>> >> +
>> >> return file->f_op->sendpage(file, buf->page, buf->offset,
sd-> len, &pos, more);
>> >> }
>>
Willy> OK it works like a charm here now ! I can't break it anymore, so it
Willy> looks like you finally got it !
>>
>> It's still broken, there's no comments in the code to explain all this
>> magic to mere mortals! *grin*
Willy> I would generally agree, but when Eric fixes such a thing, he
Willy> generally goes with lengthy details in the commit message.
I'm sure he will too, I just wanted to nudge him because while I sorta
followed this discussion, I see lots of pain down the road if the code
wasn't updated with some nice big fat comments.
Great job finding this code and testing, testing, testing.
John
^ permalink raw reply
* [PATCH 3/4 net-next] tg3: Improve PCI function number detection.
From: Michael Chan @ 2013-01-06 22:51 UTC (permalink / raw)
To: davem; +Cc: netdev, nsujir
In-Reply-To: <1357512670-17636-2-git-send-email-mchan@broadcom.com>
Simplify the code to detect PCI function number on 5717, 5719, and 5720.
If shared memory does not have proper signature, read the function number
from register directly.
Signed-off-by: Michael Chan <mchan@broadcom.com>
---
drivers/net/ethernet/broadcom/tg3.c | 19 ++++++++-----------
1 files changed, 8 insertions(+), 11 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index 6eab7d7..3596b7b 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -15441,21 +15441,18 @@ static int tg3_get_invariants(struct tg3 *tp, const struct pci_device_id *ent)
&val);
tp->pci_fn = val & 0x7;
}
- } else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717) {
- tg3_read_mem(tp, NIC_SRAM_CPMU_STATUS, &val);
- if ((val & NIC_SRAM_CPMUSTAT_SIG_MSK) ==
- NIC_SRAM_CPMUSTAT_SIG) {
- tp->pci_fn = val & TG3_CPMU_STATUS_FMSK_5717;
- tp->pci_fn = tp->pci_fn ? 1 : 0;
- }
- } else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
+ } else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) {
tg3_read_mem(tp, NIC_SRAM_CPMU_STATUS, &val);
- if ((val & NIC_SRAM_CPMUSTAT_SIG_MSK) ==
- NIC_SRAM_CPMUSTAT_SIG) {
+ if ((val & NIC_SRAM_CPMUSTAT_SIG_MSK) != NIC_SRAM_CPMUSTAT_SIG)
+ val = tr32(TG3_CPMU_STATUS);
+
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717)
+ tp->pci_fn = (val & TG3_CPMU_STATUS_FMSK_5717) ? 1 : 0;
+ else
tp->pci_fn = (val & TG3_CPMU_STATUS_FMSK_5719) >>
TG3_CPMU_STATUS_FSHFT_5719;
- }
}
/* Get eeprom hw config before calling tg3_set_power_state().
--
1.7.1
^ permalink raw reply related
* [PATCH 4/4 net-next] tg3: Remove IS_ENABLED(CONFIG_HWMON) check
From: Michael Chan @ 2013-01-06 22:51 UTC (permalink / raw)
To: davem; +Cc: netdev, nsujir
In-Reply-To: <1357512670-17636-3-git-send-email-mchan@broadcom.com>
From: Nithin Nayak Sujir <nsujir@broadcom.com>
Commit de0a41484c47d783dd4d442914815076aa2caac2 added Kconfig logic to
select HWMON and removed all the IS_ENABLED(CONFIG_HWMON) checks in the
tg3.c file. It missed this one check in the header.
Update version to 3.129 and update copyright year.
Signed-off-by: Nithin Nayak Sujir <nsujir@broadcom.com>
Signed-off-by: Michael Chan <mchan@broadcom.com>
---
drivers/net/ethernet/broadcom/tg3.c | 6 +++---
drivers/net/ethernet/broadcom/tg3.h | 4 +---
2 files changed, 4 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index 3596b7b..bc4d989 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -4,7 +4,7 @@
* Copyright (C) 2001, 2002, 2003, 2004 David S. Miller (davem@redhat.com)
* Copyright (C) 2001, 2002, 2003 Jeff Garzik (jgarzik@pobox.com)
* Copyright (C) 2004 Sun Microsystems Inc.
- * Copyright (C) 2005-2012 Broadcom Corporation.
+ * Copyright (C) 2005-2013 Broadcom Corporation.
*
* Firmware is:
* Derived from proprietary unpublished source code,
@@ -93,10 +93,10 @@ static inline void _tg3_flag_clear(enum TG3_FLAGS flag, unsigned long *bits)
#define DRV_MODULE_NAME "tg3"
#define TG3_MAJ_NUM 3
-#define TG3_MIN_NUM 128
+#define TG3_MIN_NUM 129
#define DRV_MODULE_VERSION \
__stringify(TG3_MAJ_NUM) "." __stringify(TG3_MIN_NUM)
-#define DRV_MODULE_RELDATE "December 03, 2012"
+#define DRV_MODULE_RELDATE "January 06, 2013"
#define RESET_KIND_SHUTDOWN 0
#define RESET_KIND_INIT 1
diff --git a/drivers/net/ethernet/broadcom/tg3.h b/drivers/net/ethernet/broadcom/tg3.h
index 39afc0e..9cd88a4 100644
--- a/drivers/net/ethernet/broadcom/tg3.h
+++ b/drivers/net/ethernet/broadcom/tg3.h
@@ -4,7 +4,7 @@
* Copyright (C) 2001, 2002, 2003, 2004 David S. Miller (davem@redhat.com)
* Copyright (C) 2001 Jeff Garzik (jgarzik@pobox.com)
* Copyright (C) 2004 Sun Microsystems Inc.
- * Copyright (C) 2007-2012 Broadcom Corporation.
+ * Copyright (C) 2007-2013 Broadcom Corporation.
*/
#ifndef _T3_H
@@ -3348,9 +3348,7 @@ struct tg3 {
const struct firmware *fw;
u32 fw_len; /* includes BSS */
-#if IS_ENABLED(CONFIG_HWMON)
struct device *hwmon_dev;
-#endif
bool link_up;
};
--
1.7.1
^ permalink raw reply related
* [PATCH 2/4 net-next] tg3: Add NVRAM support for 5762
From: Michael Chan @ 2013-01-06 22:51 UTC (permalink / raw)
To: davem; +Cc: netdev, nsujir
In-Reply-To: <1357512670-17636-1-git-send-email-mchan@broadcom.com>
Detect NVRAM types for 5762 and read OTP firmware version.
Signed-off-by: Michael Chan <mchan@broadcom.com>
---
drivers/net/ethernet/broadcom/tg3.c | 96 ++++++++++++++++++++++++++++++++++-
drivers/net/ethernet/broadcom/tg3.h | 15 ++++++
2 files changed, 110 insertions(+), 1 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index 01e3201..6eab7d7 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -330,6 +330,9 @@ static DEFINE_PCI_DEVICE_TABLE(tg3_pci_tbl) = {
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5719)},
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5720)},
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57762)},
+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5762)},
+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5725)},
+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5727)},
{PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9DXX)},
{PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9MXX)},
{PCI_DEVICE(PCI_VENDOR_ID_ALTIMA, PCI_DEVICE_ID_ALTIMA_AC1000)},
@@ -13714,6 +13717,20 @@ static void tg3_get_5720_nvram_info(struct tg3 *tp)
nvcfg1 = tr32(NVRAM_CFG1);
nvmpinstrp = nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK;
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5762) {
+ if (!(nvcfg1 & NVRAM_CFG1_5762VENDOR_MASK)) {
+ tg3_flag_set(tp, NO_NVRAM);
+ return;
+ }
+
+ switch (nvmpinstrp) {
+ case FLASH_5762_EEPROM_HD:
+ nvmpinstrp = FLASH_5720_EEPROM_HD;
+ case FLASH_5762_EEPROM_LD:
+ nvmpinstrp = FLASH_5720_EEPROM_LD;
+ }
+ }
+
switch (nvmpinstrp) {
case FLASH_5720_EEPROM_HD:
case FLASH_5720_EEPROM_LD:
@@ -13817,6 +13834,17 @@ static void tg3_get_5720_nvram_info(struct tg3 *tp)
tg3_nvram_get_pagesize(tp, nvcfg1);
if (tp->nvram_pagesize != 264 && tp->nvram_pagesize != 528)
tg3_flag_set(tp, NO_NVRAM_ADDR_TRANS);
+
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5762) {
+ u32 val;
+
+ if (tg3_nvram_read(tp, 0, &val))
+ return;
+
+ if (val != TG3_EEPROM_MAGIC &&
+ (val & TG3_EEPROM_MAGIC_FW_MSK) != TG3_EEPROM_MAGIC_FW)
+ tg3_flag_set(tp, NO_NVRAM);
+ }
}
/* Chips other than 5700/5701 use the NVRAM for fetching info. */
@@ -13866,7 +13894,8 @@ static void tg3_nvram_init(struct tg3 *tp)
else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719)
tg3_get_5717_nvram_info(tp);
- else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720)
+ else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5762)
tg3_get_5720_nvram_info(tp);
else
tg3_get_nvram_info(tp);
@@ -14168,6 +14197,39 @@ done:
device_set_wakeup_capable(&tp->pdev->dev, false);
}
+static int tg3_ape_otp_read(struct tg3 *tp, u32 offset, u32 *val)
+{
+ int i, err;
+ u32 val2, off = offset * 8;
+
+ err = tg3_nvram_lock(tp);
+ if (err)
+ return err;
+
+ tg3_ape_write32(tp, TG3_APE_OTP_ADDR, off | APE_OTP_ADDR_CPU_ENABLE);
+ tg3_ape_write32(tp, TG3_APE_OTP_CTRL, APE_OTP_CTRL_PROG_EN |
+ APE_OTP_CTRL_CMD_RD | APE_OTP_CTRL_START);
+ tg3_ape_read32(tp, TG3_APE_OTP_CTRL);
+ udelay(10);
+
+ for (i = 0; i < 100; i++) {
+ val2 = tg3_ape_read32(tp, TG3_APE_OTP_STATUS);
+ if (val2 & APE_OTP_STATUS_CMD_DONE) {
+ *val = tg3_ape_read32(tp, TG3_APE_OTP_RD_DATA);
+ break;
+ }
+ udelay(10);
+ }
+
+ tg3_ape_write32(tp, TG3_APE_OTP_CTRL, 0);
+
+ tg3_nvram_unlock(tp);
+ if (val2 & APE_OTP_STATUS_CMD_DONE)
+ return 0;
+
+ return -EBUSY;
+}
+
static int tg3_issue_otp_command(struct tg3 *tp, u32 cmd)
{
int i;
@@ -14708,6 +14770,8 @@ static void tg3_read_dash_ver(struct tg3 *tp)
if (tg3_flag(tp, APE_HAS_NCSI))
fwtype = "NCSI";
+ else if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_5725)
+ fwtype = "SMASH";
else
fwtype = "DASH";
@@ -14721,6 +14785,31 @@ static void tg3_read_dash_ver(struct tg3 *tp)
(apedata & APE_FW_VERSION_BLDMSK));
}
+static void tg3_read_otp_ver(struct tg3 *tp)
+{
+ u32 val, val2;
+
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5762)
+ return;
+
+ if (!tg3_ape_otp_read(tp, OTP_ADDRESS_MAGIC0, &val) &&
+ !tg3_ape_otp_read(tp, OTP_ADDRESS_MAGIC0 + 4, &val2) &&
+ TG3_OTP_MAGIC0_VALID(val)) {
+ u64 val64 = (u64) val << 32 | val2;
+ u32 ver = 0;
+ int i, vlen;
+
+ for (i = 0; i < 7; i++) {
+ if ((val64 & 0xff) == 0)
+ break;
+ ver = val64 & 0xff;
+ val64 >>= 8;
+ }
+ vlen = strlen(tp->fw_ver);
+ snprintf(&tp->fw_ver[vlen], TG3_VER_SIZE - vlen, " .%02d", ver);
+ }
+}
+
static void tg3_read_fw_ver(struct tg3 *tp)
{
u32 val;
@@ -14731,6 +14820,7 @@ static void tg3_read_fw_ver(struct tg3 *tp)
if (tg3_flag(tp, NO_NVRAM)) {
strcat(tp->fw_ver, "sb");
+ tg3_read_otp_ver(tp);
return;
}
@@ -15428,6 +15518,10 @@ static int tg3_get_invariants(struct tg3 *tp, const struct pci_device_id *ent)
GRC_LCLCTRL_GPIO_OUTPUT0;
}
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5762)
+ tp->grc_local_ctrl |=
+ tr32(GRC_LOCAL_CTRL) & GRC_LCLCTRL_GPIO_UART_SEL;
+
/* Switch out of Vaux if it is a NIC */
tg3_pwrsrc_switch_to_vmain(tp);
diff --git a/drivers/net/ethernet/broadcom/tg3.h b/drivers/net/ethernet/broadcom/tg3.h
index 46d43f7..39afc0e 100644
--- a/drivers/net/ethernet/broadcom/tg3.h
+++ b/drivers/net/ethernet/broadcom/tg3.h
@@ -1859,6 +1859,7 @@
#define FLASH_VENDOR_SST_SMALL 0x00000001
#define FLASH_VENDOR_SST_LARGE 0x02000001
#define NVRAM_CFG1_5752VENDOR_MASK 0x03c00003
+#define NVRAM_CFG1_5762VENDOR_MASK 0x03e00003
#define FLASH_5752VENDOR_ATMEL_EEPROM_64KHZ 0x00000000
#define FLASH_5752VENDOR_ATMEL_EEPROM_376KHZ 0x02000000
#define FLASH_5752VENDOR_ATMEL_FLASH_BUFFERED 0x02000003
@@ -2376,6 +2377,20 @@
#define APE_LOCK_REQ_DRIVER 0x00001000
#define TG3_APE_LOCK_GRANT 0x004c
#define APE_LOCK_GRANT_DRIVER 0x00001000
+#define TG3_APE_OTP_CTRL 0x00e8
+#define APE_OTP_CTRL_PROG_EN 0x200000
+#define APE_OTP_CTRL_CMD_RD 0x000000
+#define APE_OTP_CTRL_START 0x000001
+#define TG3_APE_OTP_STATUS 0x00ec
+#define APE_OTP_STATUS_CMD_DONE 0x000001
+#define TG3_APE_OTP_ADDR 0x00f0
+#define APE_OTP_ADDR_CPU_ENABLE 0x80000000
+#define TG3_APE_OTP_RD_DATA 0x00f8
+
+#define OTP_ADDRESS_MAGIC0 0x00000050
+#define TG3_OTP_MAGIC0_VALID(val) \
+ ((((val) & 0xf0000000) == 0xa0000000) ||\
+ (((val) & 0x0f000000) == 0x0a000000))
/* APE shared memory. Accessible through BAR1 */
#define TG3_APE_SHMEM_BASE 0x4000
--
1.7.1
^ permalink raw reply related
* [PATCH 1/4 net-next] tg3: Add support for new 5762 ASIC
From: Michael Chan @ 2013-01-06 22:51 UTC (permalink / raw)
To: davem; +Cc: netdev, nsujir
Add basic support for 5762 which is a 57765_PLUS class device.
Signed-off-by: Michael Chan <mchan@broadcom.com>
---
drivers/net/ethernet/broadcom/tg3.c | 91 +++++++++++++++++++++++++---------
drivers/net/ethernet/broadcom/tg3.h | 15 +++++-
2 files changed, 81 insertions(+), 25 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index 78ea90c..01e3201 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -2632,6 +2632,9 @@ out:
tg3_writephy(tp, MII_TG3_FET_PTEST, 0x12);
}
+ if (tp->pci_chip_rev_id == CHIPREV_ID_5762_A0)
+ tg3_phydsp_write(tp, 0xffb, 0x4000);
+
tg3_phy_toggle_automdix(tp, 1);
tg3_phy_set_wirespeed(tp);
return 0;
@@ -4037,6 +4040,7 @@ static int tg3_phy_autoneg_cfg(struct tg3 *tp, u32 advertise, u32 flowctrl)
tg3_phydsp_write(tp, MII_TG3_DSP_TAP26, val);
/* Fall through */
case ASIC_REV_5720:
+ case ASIC_REV_5762:
if (!tg3_phydsp_read(tp, MII_TG3_DSP_CH34TP2, &val))
tg3_phydsp_write(tp, MII_TG3_DSP_CH34TP2, val |
MII_TG3_DSP_CH34TP2_HIBW01);
@@ -5484,7 +5488,8 @@ static int tg3_setup_phy(struct tg3 *tp, int force_reset)
val = (2 << TX_LENGTHS_IPG_CRS_SHIFT) |
(6 << TX_LENGTHS_IPG_SHIFT);
- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720)
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5762)
val |= tr32(MAC_TX_LENGTHS) &
(TX_LENGTHS_JMB_FRM_LEN_MSK |
TX_LENGTHS_CNT_DWN_VAL_MSK);
@@ -8672,7 +8677,8 @@ static void tg3_rings_reset(struct tg3 *tp)
limit = NIC_SRAM_SEND_RCB + TG3_BDINFO_SIZE * 16;
else if (tg3_flag(tp, 5717_PLUS))
limit = NIC_SRAM_SEND_RCB + TG3_BDINFO_SIZE * 4;
- else if (tg3_flag(tp, 57765_CLASS))
+ else if (tg3_flag(tp, 57765_CLASS) ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5762)
limit = NIC_SRAM_SEND_RCB + TG3_BDINFO_SIZE * 2;
else
limit = NIC_SRAM_SEND_RCB + TG3_BDINFO_SIZE;
@@ -8689,6 +8695,7 @@ static void tg3_rings_reset(struct tg3 *tp)
else if (!tg3_flag(tp, 5705_PLUS))
limit = NIC_SRAM_RCV_RET_RCB + TG3_BDINFO_SIZE * 16;
else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5762 ||
tg3_flag(tp, 57765_CLASS))
limit = NIC_SRAM_RCV_RET_RCB + TG3_BDINFO_SIZE * 4;
else
@@ -8979,9 +8986,12 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
/* Enable MAC control of LPI */
if (tp->phy_flags & TG3_PHYFLG_EEE_CAP) {
- tw32_f(TG3_CPMU_EEE_LNKIDL_CTRL,
- TG3_CPMU_EEE_LNKIDL_PCIE_NL0 |
- TG3_CPMU_EEE_LNKIDL_UART_IDL);
+ val = TG3_CPMU_EEE_LNKIDL_PCIE_NL0 |
+ TG3_CPMU_EEE_LNKIDL_UART_IDL;
+ if (tp->pci_chip_rev_id == CHIPREV_ID_57765_A0)
+ val |= TG3_CPMU_EEE_LNKIDL_APE_TX_MT;
+
+ tw32_f(TG3_CPMU_EEE_LNKIDL_CTRL, val);
tw32_f(TG3_CPMU_EEE_CTRL,
TG3_CPMU_EEE_CTRL_EXIT_20_1_US);
@@ -9156,7 +9166,8 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
if (tp->pci_chip_rev_id == CHIPREV_ID_57765_A0)
val &= ~DMA_RWCTRL_CRDRDR_RDMA_MRRS_MSK;
if (!tg3_flag(tp, 57765_CLASS) &&
- GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5717)
+ GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5717 &&
+ GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5762)
val |= DMA_RWCTRL_TAGGED_STAT_WA;
tw32(TG3PCI_DMA_RW_CTRL, val | tp->dma_rwctrl);
} else if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5784 &&
@@ -9308,7 +9319,8 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_MAXLEN_FLAGS,
val | BDINFO_FLAGS_USE_EXT_RECV);
if (!tg3_flag(tp, USE_JUMBO_BDFLAG) ||
- tg3_flag(tp, 57765_CLASS))
+ tg3_flag(tp, 57765_CLASS) ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5762)
tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_NIC_ADDR,
NIC_SRAM_RX_JUMBO_BUFFER_DESC);
} else {
@@ -9350,7 +9362,8 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
(6 << TX_LENGTHS_IPG_SHIFT) |
(32 << TX_LENGTHS_SLOT_TIME_SHIFT);
- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720)
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5762)
val |= tr32(MAC_TX_LENGTHS) &
(TX_LENGTHS_JMB_FRM_LEN_MSK |
TX_LENGTHS_CNT_DWN_VAL_MSK);
@@ -9404,7 +9417,8 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780)
rdmac_mode |= RDMAC_MODE_IPV6_LSO_EN;
- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720)
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5762)
rdmac_mode |= tr32(RDMAC_MODE) & RDMAC_MODE_H2BNC_VLAN_DET;
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
@@ -9412,8 +9426,16 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 ||
tg3_flag(tp, 57765_PLUS)) {
- val = tr32(TG3_RDMA_RSRVCTRL_REG);
- if (tp->pci_chip_rev_id == CHIPREV_ID_5719_A0) {
+ u32 tgtreg;
+
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5762)
+ tgtreg = TG3_RDMA_RSRVCTRL_REG2;
+ else
+ tgtreg = TG3_RDMA_RSRVCTRL_REG;
+
+ val = tr32(tgtreg);
+ if (tp->pci_chip_rev_id == CHIPREV_ID_5719_A0 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5762) {
val &= ~(TG3_RDMA_RSRVCTRL_TXMRGN_MASK |
TG3_RDMA_RSRVCTRL_FIFO_LWM_MASK |
TG3_RDMA_RSRVCTRL_FIFO_HWM_MASK);
@@ -9421,14 +9443,21 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
TG3_RDMA_RSRVCTRL_FIFO_LWM_1_5K |
TG3_RDMA_RSRVCTRL_FIFO_HWM_1_5K;
}
- tw32(TG3_RDMA_RSRVCTRL_REG,
- val | TG3_RDMA_RSRVCTRL_FIFO_OFLW_FIX);
+ tw32(tgtreg, val | TG3_RDMA_RSRVCTRL_FIFO_OFLW_FIX);
}
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) {
- val = tr32(TG3_LSO_RD_DMA_CRPTEN_CTRL);
- tw32(TG3_LSO_RD_DMA_CRPTEN_CTRL, val |
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5762) {
+ u32 tgtreg;
+
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5762)
+ tgtreg = TG3_LSO_RD_DMA_CRPTEN_CTRL2;
+ else
+ tgtreg = TG3_LSO_RD_DMA_CRPTEN_CTRL;
+
+ val = tr32(tgtreg);
+ tw32(tgtreg, val |
TG3_LSO_RD_DMA_CRPTEN_CTRL_BLEN_BD_4K |
TG3_LSO_RD_DMA_CRPTEN_CTRL_BLEN_LSO_4K);
}
@@ -9661,7 +9690,8 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
tp->tx_mode |= TX_MODE_MBUF_LOCKUP_FIX;
- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) {
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5762) {
val = TX_MODE_JMB_FRM_LEN | TX_MODE_CNT_DN_MODE;
tp->tx_mode &= ~val;
tp->tx_mode |= tr32(MAC_TX_MODE) & val;
@@ -12342,7 +12372,8 @@ static int tg3_test_memory(struct tg3 *tp)
if (tg3_flag(tp, 5717_PLUS))
mem_tbl = mem_tbl_5717;
- else if (tg3_flag(tp, 57765_CLASS))
+ else if (tg3_flag(tp, 57765_CLASS) ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5762)
mem_tbl = mem_tbl_57765;
else if (tg3_flag(tp, 5755_PLUS))
mem_tbl = mem_tbl_5755;
@@ -14296,6 +14327,7 @@ static int tg3_phy_probe(struct tg3 *tp)
if (!(tp->phy_flags & TG3_PHYFLG_ANY_SERDES) &&
(GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5762 ||
(tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718 &&
tp->pci_chip_rev_id != CHIPREV_ID_5717_A0) ||
(GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765 &&
@@ -14785,7 +14817,10 @@ static void tg3_detect_asic_rev(struct tg3 *tp, u32 misc_ctrl_reg)
tp->pdev->device == TG3PCI_DEVICE_TIGON3_5717_C ||
tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718 ||
tp->pdev->device == TG3PCI_DEVICE_TIGON3_5719 ||
- tp->pdev->device == TG3PCI_DEVICE_TIGON3_5720)
+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_5720 ||
+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_5762 ||
+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_5725 ||
+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_5727)
reg = TG3PCI_GEN2_PRODID_ASICREV;
else if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_57781 ||
tp->pdev->device == TG3PCI_DEVICE_TIGON3_57785 ||
@@ -14822,7 +14857,8 @@ static void tg3_detect_asic_rev(struct tg3 *tp, u32 misc_ctrl_reg)
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57766)
tg3_flag_set(tp, 57765_CLASS);
- if (tg3_flag(tp, 57765_CLASS) || tg3_flag(tp, 5717_PLUS))
+ if (tg3_flag(tp, 57765_CLASS) || tg3_flag(tp, 5717_PLUS) ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5762)
tg3_flag_set(tp, 57765_PLUS);
/* Intentionally exclude ASIC_REV_5906 */
@@ -15113,7 +15149,8 @@ static int tg3_get_invariants(struct tg3 *tp, const struct pci_device_id *ent)
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720)
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5762)
tg3_flag_set(tp, LRG_PROD_RING_CAP);
if (tg3_flag(tp, 57765_PLUS) &&
@@ -15481,7 +15518,8 @@ static int tg3_get_invariants(struct tg3 *tp, const struct pci_device_id *ent)
/* Initialize data/descriptor byte/word swapping. */
val = tr32(GRC_MODE);
- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720)
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5762)
val &= (GRC_MODE_BYTE_SWAP_B2HRX_DATA |
GRC_MODE_WORD_SWAP_B2HRX_DATA |
GRC_MODE_B2HRX_ENABLE |
@@ -16238,6 +16276,7 @@ static char *tg3_phy_string(struct tg3 *tp)
case TG3_PHY_ID_BCM57765: return "57765";
case TG3_PHY_ID_BCM5719C: return "5719C";
case TG3_PHY_ID_BCM5720C: return "5720C";
+ case TG3_PHY_ID_BCM5762: return "5762C";
case TG3_PHY_ID_BCM8002: return "8002/serdes";
case 0: return "serdes";
default: return "unknown";
@@ -16413,7 +16452,10 @@ static int tg3_init_one(struct pci_dev *pdev,
tp->pdev->device == TG3PCI_DEVICE_TIGON3_5717_C ||
tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718 ||
tp->pdev->device == TG3PCI_DEVICE_TIGON3_5719 ||
- tp->pdev->device == TG3PCI_DEVICE_TIGON3_5720) {
+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_5720 ||
+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_5762 ||
+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_5725 ||
+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_5727) {
tg3_flag_set(tp, ENABLE_APE);
tp->aperegs = pci_ioremap_bar(pdev, BAR_2);
if (!tp->aperegs) {
@@ -16608,7 +16650,8 @@ static int tg3_init_one(struct pci_dev *pdev,
pci_set_drvdata(pdev, dev);
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720)
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5762)
tg3_flag_set(tp, PTP_CAPABLE);
if (tg3_flag(tp, 5717_PLUS)) {
diff --git a/drivers/net/ethernet/broadcom/tg3.h b/drivers/net/ethernet/broadcom/tg3.h
index 247d954..46d43f7 100644
--- a/drivers/net/ethernet/broadcom/tg3.h
+++ b/drivers/net/ethernet/broadcom/tg3.h
@@ -65,6 +65,9 @@
#define TG3PCI_DEVICE_TIGON3_57766 0x1686
#define TG3PCI_DEVICE_TIGON3_57786 0x16b3
#define TG3PCI_DEVICE_TIGON3_57782 0x16b7
+#define TG3PCI_DEVICE_TIGON3_5762 0x1687
+#define TG3PCI_DEVICE_TIGON3_5725 0x1643
+#define TG3PCI_DEVICE_TIGON3_5727 0x16f3
/* 0x04 --> 0x2c unused */
#define TG3PCI_SUBVENDOR_ID_BROADCOM PCI_VENDOR_ID_BROADCOM
#define TG3PCI_SUBDEVICE_ID_BROADCOM_95700A6 0x1644
@@ -159,6 +162,7 @@
#define CHIPREV_ID_57765_A0 0x57785000
#define CHIPREV_ID_5719_A0 0x05719000
#define CHIPREV_ID_5720_A0 0x05720000
+#define CHIPREV_ID_5762_A0 0x05762000
#define GET_ASIC_REV(CHIP_REV_ID) ((CHIP_REV_ID) >> 12)
#define ASIC_REV_5700 0x07
#define ASIC_REV_5701 0x00
@@ -182,6 +186,7 @@
#define ASIC_REV_5719 0x5719
#define ASIC_REV_5720 0x5720
#define ASIC_REV_57766 0x57766
+#define ASIC_REV_5762 0x5762
#define GET_CHIP_REV(CHIP_REV_ID) ((CHIP_REV_ID) >> 8)
#define CHIPREV_5700_AX 0x70
#define CHIPREV_5700_BX 0x71
@@ -1178,6 +1183,7 @@
#define TG3_CPMU_EEE_LNKIDL_CTRL 0x000036bc
#define TG3_CPMU_EEE_LNKIDL_PCIE_NL0 0x01000000
#define TG3_CPMU_EEE_LNKIDL_UART_IDL 0x00000004
+#define TG3_CPMU_EEE_LNKIDL_APE_TX_MT 0x00000002
/* 0x36c0 --> 0x36d0 unused */
#define TG3_CPMU_EEE_CTRL 0x000036d0
@@ -1400,7 +1406,10 @@
#define RDMAC_STATUS_FIFOURUN 0x00000080
#define RDMAC_STATUS_FIFOOREAD 0x00000100
#define RDMAC_STATUS_LNGREAD 0x00000200
-/* 0x4808 --> 0x4900 unused */
+/* 0x4808 --> 0x4890 unused */
+
+#define TG3_RDMA_RSRVCTRL_REG2 0x00004890
+#define TG3_LSO_RD_DMA_CRPTEN_CTRL2 0x000048a0
#define TG3_RDMA_RSRVCTRL_REG 0x00004900
#define TG3_RDMA_RSRVCTRL_FIFO_OFLW_FIX 0x00000004
@@ -1910,6 +1919,8 @@
#define FLASH_5717VENDOR_ST_45USPT 0x03400001
#define FLASH_5720_EEPROM_HD 0x00000001
#define FLASH_5720_EEPROM_LD 0x00000003
+#define FLASH_5762_EEPROM_HD 0x02000001
+#define FLASH_5762_EEPROM_LD 0x02000003
#define FLASH_5720VENDOR_M_ATMEL_DB011D 0x01000000
#define FLASH_5720VENDOR_M_ATMEL_DB021D 0x01000002
#define FLASH_5720VENDOR_M_ATMEL_DB041D 0x01000001
@@ -3206,6 +3217,7 @@ struct tg3 {
#define TG3_PHY_ID_BCM57765 0x5c0d8a40
#define TG3_PHY_ID_BCM5719C 0x5c0d8a20
#define TG3_PHY_ID_BCM5720C 0x5c0d8b60
+#define TG3_PHY_ID_BCM5762 0x85803780
#define TG3_PHY_ID_BCM5906 0xdc00ac40
#define TG3_PHY_ID_BCM8002 0x60010140
#define TG3_PHY_ID_INVALID 0xffffffff
@@ -3230,6 +3242,7 @@ struct tg3 {
(X) == TG3_PHY_ID_BCM5906 || (X) == TG3_PHY_ID_BCM5761 || \
(X) == TG3_PHY_ID_BCM5718C || (X) == TG3_PHY_ID_BCM5718S || \
(X) == TG3_PHY_ID_BCM57765 || (X) == TG3_PHY_ID_BCM5719C || \
+ (X) == TG3_PHY_ID_BCM5720C || (X) == TG3_PHY_ID_BCM5762 || \
(X) == TG3_PHY_ID_BCM8002)
u32 phy_flags;
--
1.7.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox