Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1576113 > unrolled thread
| Started by | Shannon Nelson <shannon.nelson@oracle.com> |
|---|---|
| First post | 2017-02-07 23:20 +0100 |
| Last post | 2017-02-07 23:30 +0100 |
| Articles | 14 — 3 participants |
Back to article view | Back to linux.kernel
[PATCH v2 net-next 0/9] sunvnet driver updates Shannon Nelson <shannon.nelson@oracle.com> - 2017-02-07 23:20 +0100
[PATCH v2 net-next 8/9] ldmvsw: update and simplify version string Shannon Nelson <shannon.nelson@oracle.com> - 2017-02-07 23:20 +0100
[PATCH v2 net-next 2/9] sunvnet: remove unused variable in maybe_tx_wakeup Shannon Nelson <shannon.nelson@oracle.com> - 2017-02-07 23:20 +0100
[PATCH v2 net-next 6/9] sunvnet: straighten up message event handling logic Shannon Nelson <shannon.nelson@oracle.com> - 2017-02-07 23:20 +0100
Re: [PATCH v2 net-next 6/9] sunvnet: straighten up message event handling logic Sowmini Varadhan <sowmini.varadhan@oracle.com> - 2017-02-08 17:10 +0100
Re: [PATCH v2 net-next 6/9] sunvnet: straighten up message event handling logic Sowmini Varadhan <sowmini.varadhan@oracle.com> - 2017-02-08 17:40 +0100
Re: [PATCH v2 net-next 6/9] sunvnet: straighten up message event handling logic Shannon Nelson <shannon.nelson@oracle.com> - 2017-02-08 17:40 +0100
[PATCH v2 net-next 5/9] sunvnet: add memory barrier before check for tx enable Shannon Nelson <shannon.nelson@oracle.com> - 2017-02-07 23:20 +0100
[PATCH v2 net-next 1/9] sunvnet: make sunvnet common code dynamically loadable Shannon Nelson <shannon.nelson@oracle.com> - 2017-02-07 23:20 +0100
Re: [PATCH v2 net-next 1/9] sunvnet: make sunvnet common code dynamically loadable David Miller <davem@davemloft.net> - 2017-02-08 20:40 +0100
Re: [PATCH v2 net-next 1/9] sunvnet: make sunvnet common code dynamically loadable Shannon Nelson <shannon.nelson@oracle.com> - 2017-02-08 23:00 +0100
[PATCH v2 net-next 4/9] sunvnet: add driver stats for ethtool support Shannon Nelson <shannon.nelson@oracle.com> - 2017-02-07 23:20 +0100
[PATCH v2 net-next 9/9] ldmvsw: disable tso and gso for bridge operations Shannon Nelson <shannon.nelson@oracle.com> - 2017-02-07 23:20 +0100
[PATCH v2 net-next 7/9] sunvnet: remove extra rcu_read_unlocks Shannon Nelson <shannon.nelson@oracle.com> - 2017-02-07 23:30 +0100
| From | Shannon Nelson <shannon.nelson@oracle.com> |
|---|---|
| Date | 2017-02-07 23:20 +0100 |
| Subject | [PATCH v2 net-next 0/9] sunvnet driver updates |
| Message-ID | <t8mhb-fy-3@gated-at.bofh.it> |
The sunvnet ldom virtual network driver was due for some updates and a bugfix or two. These patches address a few items left over from last year's make-over. v2: - changed memory barrier fix to use smp_wmb - put NETIF_F_SG back into the advertised ldmvsw hw_features Shannon Nelson (8): sunvnet: make sunvnet common code dynamically loadable sunvnet: update version and version printing sunvnet: add driver stats for ethtool support sunvnet: add memory barrier before check for tx enable sunvnet: straighten up message event handling logic sunvnet: remove extra rcu_read_unlocks ldmvsw: update and simplify version string ldmvsw: disable tso and gso for bridge operations Sowmini Varadhan (1): sunvnet: remove unused variable in maybe_tx_wakeup drivers/net/ethernet/sun/Kconfig | 8 +- drivers/net/ethernet/sun/ldmvsw.c | 82 ++++++++++++++--- drivers/net/ethernet/sun/sunvnet.c | 77 ++++++++++++++-- drivers/net/ethernet/sun/sunvnet_common.c | 143 ++++++++++++++++------------ 4 files changed, 224 insertions(+), 86 deletions(-)
[toc] | [next] | [standalone]
| From | Shannon Nelson <shannon.nelson@oracle.com> |
|---|---|
| Date | 2017-02-07 23:20 +0100 |
| Subject | [PATCH v2 net-next 8/9] ldmvsw: update and simplify version string |
| Message-ID | <t8mhb-fy-7@gated-at.bofh.it> |
| In reply to | #1576113 |
New version and simplify the print code.
Signed-off-by: Shannon Nelson <shannon.nelson@oracle.com>
---
drivers/net/ethernet/sun/ldmvsw.c | 14 ++++----------
1 files changed, 4 insertions(+), 10 deletions(-)
diff --git a/drivers/net/ethernet/sun/ldmvsw.c b/drivers/net/ethernet/sun/ldmvsw.c
index 3999fb7..3ef5c08 100644
--- a/drivers/net/ethernet/sun/ldmvsw.c
+++ b/drivers/net/ethernet/sun/ldmvsw.c
@@ -41,11 +41,11 @@
static u8 vsw_port_hwaddr[ETH_ALEN] = {0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
#define DRV_MODULE_NAME "ldmvsw"
-#define DRV_MODULE_VERSION "1.0"
-#define DRV_MODULE_RELDATE "Jan 15, 2016"
+#define DRV_MODULE_VERSION "1.1"
+#define DRV_MODULE_RELDATE "February 3, 2017"
static char version[] =
- DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
+ DRV_MODULE_NAME " " DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")";
MODULE_AUTHOR("Oracle");
MODULE_DESCRIPTION("Sun4v LDOM Virtual Switch Driver");
MODULE_LICENSE("GPL");
@@ -322,11 +322,6 @@ static void vsw_poll_controller(struct net_device *dev)
.handshake_complete = sunvnet_handshake_complete_common,
};
-static void print_version(void)
-{
- printk_once(KERN_INFO "%s", version);
-}
-
static const char *remote_macaddr_prop = "remote-mac-address";
static const char *id_prop = "id";
@@ -342,8 +337,6 @@ static int vsw_port_probe(struct vio_dev *vdev, const struct vio_device_id *id)
const u64 *port_id;
u64 handle;
- print_version();
-
hp = mdesc_grab();
rmac = mdesc_get_property(hp, vdev->mp, remote_macaddr_prop, &len);
@@ -520,6 +513,7 @@ static void vsw_cleanup(void)
static int __init vsw_init(void)
{
+ pr_info("%s\n", version);
return vio_register_driver(&vsw_port_driver);
}
--
1.7.1
[toc] | [prev] | [next] | [standalone]
| From | Shannon Nelson <shannon.nelson@oracle.com> |
|---|---|
| Date | 2017-02-07 23:20 +0100 |
| Subject | [PATCH v2 net-next 2/9] sunvnet: remove unused variable in maybe_tx_wakeup |
| Message-ID | <t8mhb-fy-13@gated-at.bofh.it> |
| In reply to | #1576113 |
From: Sowmini Varadhan <sowmini.varadhan@oracle.com>
The vio_dring_state *dr variable is unused in maybe_tx_wakeup().
As the comments indicate, we call maybe_tx_wakeup() whenever we
get a STOPPED LDC message on the port. If the queue is stopped,
we want to wake it up so that we will send another START message
at the next TX and trigger the consumer to drain the dring.
Signed-off-by: Sowmini Varadhan <sowmini.varadhan@oracle.com>
Signed-off-by: Shannon Nelson <shannon.nelson@oracle.com>
---
drivers/net/ethernet/sun/sunvnet_common.c | 6 +-----
1 files changed, 1 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/sun/sunvnet_common.c b/drivers/net/ethernet/sun/sunvnet_common.c
index e03cf13..add22d4 100644
--- a/drivers/net/ethernet/sun/sunvnet_common.c
+++ b/drivers/net/ethernet/sun/sunvnet_common.c
@@ -743,12 +743,8 @@ static void maybe_tx_wakeup(struct vnet_port *port)
txq = netdev_get_tx_queue(VNET_PORT_TO_NET_DEVICE(port),
port->q_index);
__netif_tx_lock(txq, smp_processor_id());
- if (likely(netif_tx_queue_stopped(txq))) {
- struct vio_dring_state *dr;
-
- dr = &port->vio.drings[VIO_DRIVER_TX_RING];
+ if (likely(netif_tx_queue_stopped(txq)))
netif_tx_wake_queue(txq);
- }
__netif_tx_unlock(txq);
}
--
1.7.1
[toc] | [prev] | [next] | [standalone]
| From | Shannon Nelson <shannon.nelson@oracle.com> |
|---|---|
| Date | 2017-02-07 23:20 +0100 |
| Subject | [PATCH v2 net-next 6/9] sunvnet: straighten up message event handling logic |
| Message-ID | <t8mhb-fy-11@gated-at.bofh.it> |
| In reply to | #1576113 |
The use of gotos for handling the incoming events made this code
harder to read and support than it should be. This patch straightens
out and clears up the logic.
Signed-off-by: Shannon Nelson <shannon.nelson@oracle.com>
---
drivers/net/ethernet/sun/sunvnet_common.c | 94 ++++++++++++++---------------
1 files changed, 45 insertions(+), 49 deletions(-)
diff --git a/drivers/net/ethernet/sun/sunvnet_common.c b/drivers/net/ethernet/sun/sunvnet_common.c
index 6cb625a..d2aed2c 100644
--- a/drivers/net/ethernet/sun/sunvnet_common.c
+++ b/drivers/net/ethernet/sun/sunvnet_common.c
@@ -764,41 +764,37 @@ static int vnet_event_napi(struct vnet_port *port, int budget)
struct vio_driver_state *vio = &port->vio;
int tx_wakeup, err;
int npkts = 0;
- int event = (port->rx_event & LDC_EVENT_RESET);
-
-ldc_ctrl:
- if (unlikely(event == LDC_EVENT_RESET ||
- event == LDC_EVENT_UP)) {
- vio_link_state_change(vio, event);
-
- if (event == LDC_EVENT_RESET) {
- vnet_port_reset(port);
- vio_port_up(vio);
-
- /* If the device is running but its tx queue was
- * stopped (due to flow control), restart it.
- * This is necessary since vnet_port_reset()
- * clears the tx drings and thus we may never get
- * back a VIO_TYPE_DATA ACK packet - which is
- * the normal mechanism to restart the tx queue.
- */
- if (netif_running(dev))
- maybe_tx_wakeup(port);
- }
+
+ /* we don't expect any other bits */
+ BUG_ON(port->rx_event & ~(LDC_EVENT_DATA_READY |
+ LDC_EVENT_RESET |
+ LDC_EVENT_UP));
+
+ /* RESET takes precedent over any other event */
+ if (port->rx_event & LDC_EVENT_RESET) {
+ vio_link_state_change(vio, LDC_EVENT_RESET);
+ vnet_port_reset(port);
+ vio_port_up(vio);
+
+ /* If the device is running but its tx queue was
+ * stopped (due to flow control), restart it.
+ * This is necessary since vnet_port_reset()
+ * clears the tx drings and thus we may never get
+ * back a VIO_TYPE_DATA ACK packet - which is
+ * the normal mechanism to restart the tx queue.
+ */
+ if (netif_running(dev))
+ maybe_tx_wakeup(port);
+
port->rx_event = 0;
return 0;
}
- /* We may have multiple LDC events in rx_event. Unroll send_events() */
- event = (port->rx_event & LDC_EVENT_UP);
- port->rx_event &= ~(LDC_EVENT_RESET | LDC_EVENT_UP);
- if (event == LDC_EVENT_UP)
- goto ldc_ctrl;
- event = port->rx_event;
- if (!(event & LDC_EVENT_DATA_READY))
- return 0;
- /* we dont expect any other bits than RESET, UP, DATA_READY */
- BUG_ON(event != LDC_EVENT_DATA_READY);
+ if (port->rx_event & LDC_EVENT_UP) {
+ vio_link_state_change(vio, LDC_EVENT_UP);
+ port->rx_event = 0;
+ return 0;
+ }
err = 0;
tx_wakeup = 0;
@@ -821,25 +817,25 @@ static int vnet_event_napi(struct vnet_port *port, int budget)
pkt->start_idx = vio_dring_next(dr,
port->napi_stop_idx);
pkt->end_idx = -1;
- goto napi_resume;
- }
- err = ldc_read(vio->lp, &msgbuf, sizeof(msgbuf));
- if (unlikely(err < 0)) {
- if (err == -ECONNRESET)
- vio_conn_reset(vio);
- break;
+ } else {
+ err = ldc_read(vio->lp, &msgbuf, sizeof(msgbuf));
+ if (unlikely(err < 0)) {
+ if (err == -ECONNRESET)
+ vio_conn_reset(vio);
+ break;
+ }
+ if (err == 0)
+ break;
+ viodbg(DATA, "TAG [%02x:%02x:%04x:%08x]\n",
+ msgbuf.tag.type,
+ msgbuf.tag.stype,
+ msgbuf.tag.stype_env,
+ msgbuf.tag.sid);
+ err = vio_validate_sid(vio, &msgbuf.tag);
+ if (err < 0)
+ break;
}
- if (err == 0)
- break;
- viodbg(DATA, "TAG [%02x:%02x:%04x:%08x]\n",
- msgbuf.tag.type,
- msgbuf.tag.stype,
- msgbuf.tag.stype_env,
- msgbuf.tag.sid);
- err = vio_validate_sid(vio, &msgbuf.tag);
- if (err < 0)
- break;
-napi_resume:
+
if (likely(msgbuf.tag.type == VIO_TYPE_DATA)) {
if (msgbuf.tag.stype == VIO_SUBTYPE_INFO) {
if (!sunvnet_port_is_up_common(port)) {
--
1.7.1
[toc] | [prev] | [next] | [standalone]
| From | Sowmini Varadhan <sowmini.varadhan@oracle.com> |
|---|---|
| Date | 2017-02-08 17:10 +0100 |
| Subject | Re: [PATCH v2 net-next 6/9] sunvnet: straighten up message event handling logic |
| Message-ID | <t8CYF-2tE-1@gated-at.bofh.it> |
| In reply to | #1576116 |
On (02/07/17 14:12), Shannon Nelson wrote:
> +
> + /* we don't expect any other bits */
> + BUG_ON(port->rx_event & ~(LDC_EVENT_DATA_READY |
> + LDC_EVENT_RESET |
> + LDC_EVENT_UP));
> +
> + /* RESET takes precedent over any other event */
> + if (port->rx_event & LDC_EVENT_RESET) {
:
> port->rx_event = 0;
> return 0;
> }
> + if (port->rx_event & LDC_EVENT_UP) {
> + vio_link_state_change(vio, LDC_EVENT_UP);
> + port->rx_event = 0;
> + return 0;
> + }
>
> err = 0;
> tx_wakeup = 0;
IIRC there were timing-related situations where you can get woken up with
both UP and DATA_READY, and if my reading of your patch is
correct, we would ignore the DATA_READY, and return, right?
--Sowmini
[toc] | [prev] | [next] | [standalone]
| From | Sowmini Varadhan <sowmini.varadhan@oracle.com> |
|---|---|
| Date | 2017-02-08 17:40 +0100 |
| Subject | Re: [PATCH v2 net-next 6/9] sunvnet: straighten up message event handling logic |
| Message-ID | <t8DrI-2DS-15@gated-at.bofh.it> |
| In reply to | #1576672 |
On (02/08/17 08:28), Shannon Nelson wrote: > The existing code does this as well - if it first finds a RESET, it handles > it then hits the return 0. Next if it finds the UP, it does the goto back > to the ldc_ctrl: to process, and hits the same return 0. Only if neither of > these bits have been seen does the code move on to process the DATA_READY > event. > > If we're seeing cases of both UP and DATA_READY, then yes we'll wnat to look > at changing this logic. I think that should be a separate patch. > Ok. probably we just make one redundant loop out and back into the function. Other than that, the patchset looks good to me. --Sowmini
[toc] | [prev] | [next] | [standalone]
| From | Shannon Nelson <shannon.nelson@oracle.com> |
|---|---|
| Date | 2017-02-08 17:40 +0100 |
| Subject | Re: [PATCH v2 net-next 6/9] sunvnet: straighten up message event handling logic |
| Message-ID | <t8DrI-2DS-17@gated-at.bofh.it> |
| In reply to | #1576672 |
On 2/8/2017 7:59 AM, Sowmini Varadhan wrote:
> On (02/07/17 14:12), Shannon Nelson wrote:
>> +
>> + /* we don't expect any other bits */
>> + BUG_ON(port->rx_event & ~(LDC_EVENT_DATA_READY |
>> + LDC_EVENT_RESET |
>> + LDC_EVENT_UP));
>> +
>> + /* RESET takes precedent over any other event */
>> + if (port->rx_event & LDC_EVENT_RESET) {
> :
>> port->rx_event = 0;
>> return 0;
>> }
>> + if (port->rx_event & LDC_EVENT_UP) {
>> + vio_link_state_change(vio, LDC_EVENT_UP);
>> + port->rx_event = 0;
>> + return 0;
>> + }
>>
>> err = 0;
>> tx_wakeup = 0;
>
> IIRC there were timing-related situations where you can get woken up with
> both UP and DATA_READY, and if my reading of your patch is
> correct, we would ignore the DATA_READY, and return, right?
>
> --Sowmini
The existing code does this as well - if it first finds a RESET, it
handles it then hits the return 0. Next if it finds the UP, it does the
goto back to the ldc_ctrl: to process, and hits the same return 0. Only
if neither of these bits have been seen does the code move on to process
the DATA_READY event.
If we're seeing cases of both UP and DATA_READY, then yes we'll wnat to
look at changing this logic. I think that should be a separate patch.
sln
[toc] | [prev] | [next] | [standalone]
| From | Shannon Nelson <shannon.nelson@oracle.com> |
|---|---|
| Date | 2017-02-07 23:20 +0100 |
| Subject | [PATCH v2 net-next 5/9] sunvnet: add memory barrier before check for tx enable |
| Message-ID | <t8mhc-fy-21@gated-at.bofh.it> |
| In reply to | #1576113 |
In order to allow the underlying LDC and outstanding memory operations
to potentially catch up with the driver's Tx requests, add a memory
barrier before checking again for available tx descriptors.
Signed-off-by: Shannon Nelson <shannon.nelson@oracle.com>
---
drivers/net/ethernet/sun/sunvnet_common.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/drivers/net/ethernet/sun/sunvnet_common.c b/drivers/net/ethernet/sun/sunvnet_common.c
index 82273e6..6cb625a 100644
--- a/drivers/net/ethernet/sun/sunvnet_common.c
+++ b/drivers/net/ethernet/sun/sunvnet_common.c
@@ -1453,6 +1453,7 @@ int sunvnet_start_xmit_common(struct sk_buff *skb, struct net_device *dev,
dr->prod = (dr->prod + 1) & (VNET_TX_RING_SIZE - 1);
if (unlikely(vnet_tx_dring_avail(dr) < 1)) {
netif_tx_stop_queue(txq);
+ smp_rmb();
if (vnet_tx_dring_avail(dr) > VNET_TX_WAKEUP_THRESH(dr))
netif_tx_wake_queue(txq);
}
--
1.7.1
[toc] | [prev] | [next] | [standalone]
| From | Shannon Nelson <shannon.nelson@oracle.com> |
|---|---|
| Date | 2017-02-07 23:20 +0100 |
| Subject | [PATCH v2 net-next 1/9] sunvnet: make sunvnet common code dynamically loadable |
| Message-ID | <t8mhb-fy-17@gated-at.bofh.it> |
| In reply to | #1576113 |
When the sunvnet_common code was split out for use by both sunvnet
and the newer ldmvsw, it was made into a static kernel library, which
limits the usefulness of sunvnet and ldmvsw as loadables, since most
of the real work is being done in the shared code. Also, this is
simply dead code in kernels that aren't running the LDoms.
This patch makes the sunvnet_common into a dynamically loadable
module and makes sunvnet and ldmvsw dependent on sunvnet_common.
Signed-off-by: Shannon Nelson <shannon.nelson@oracle.com>
---
drivers/net/ethernet/sun/Kconfig | 8 ++++++--
drivers/net/ethernet/sun/sunvnet_common.c | 29 +++++++++++++++++++++++++++++
2 files changed, 35 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/sun/Kconfig b/drivers/net/ethernet/sun/Kconfig
index a4b40e3..a7d91da 100644
--- a/drivers/net/ethernet/sun/Kconfig
+++ b/drivers/net/ethernet/sun/Kconfig
@@ -70,19 +70,23 @@ config CASSINI
<http://docs.oracle.com/cd/E19113-01/giga.ether.pci/817-4341-10/817-4341-10.pdf>.
config SUNVNET_COMMON
- bool
+ tristate "Common routines to support Sun Virtual Networking"
depends on SUN_LDOMS
- default y if SUN_LDOMS
+ default m if SUN_LDOMS
config SUNVNET
tristate "Sun Virtual Network support"
+ default m
depends on SUN_LDOMS
+ depends on SUNVNET_COMMON
---help---
Support for virtual network devices under Sun Logical Domains.
config LDMVSW
tristate "Sun4v LDoms Virtual Switch support"
+ default m
depends on SUN_LDOMS
+ depends on SUNVNET_COMMON
---help---
Support for virtual switch devices under Sun4v Logical Domains.
This driver adds a network interface for every vsw-port node
diff --git a/drivers/net/ethernet/sun/sunvnet_common.c b/drivers/net/ethernet/sun/sunvnet_common.c
index 191c8ad..e03cf13 100644
--- a/drivers/net/ethernet/sun/sunvnet_common.c
+++ b/drivers/net/ethernet/sun/sunvnet_common.c
@@ -37,6 +37,35 @@
*/
#define VNET_MAX_RETRIES 10
+#define DRV_MODULE_NAME "sunvnet_common"
+#define DRV_MODULE_VERSION "1.1"
+#define DRV_MODULE_RELDATE "February 3, 2017"
+
+static char version[] =
+ DRV_MODULE_NAME " " DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")";
+MODULE_AUTHOR("David S. Miller (davem@davemloft.net)");
+MODULE_DESCRIPTION("Sun LDOM virtual network support library");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_MODULE_VERSION);
+
+static int __init sunvnet_common_init(void)
+{
+ pr_info("%s\n", version);
+ return 0;
+}
+module_init(sunvnet_common_init);
+
+static void __exit sunvnet_common_exit(void)
+{
+ /* Empty function, just here to fill the exit function pointer
+ * slot. In some combinations of older gcc and newer kernel,
+ * leaving this undefined results in the kernel marking it as a
+ * permanent module; it will show up in lsmod output as [permanent]
+ * and not be unloadable.
+ */
+}
+module_exit(sunvnet_common_exit);
+
static int __vnet_tx_trigger(struct vnet_port *port, u32 start);
static void vnet_port_reset(struct vnet_port *port);
--
1.7.1
[toc] | [prev] | [next] | [standalone]
| From | David Miller <davem@davemloft.net> |
|---|---|
| Date | 2017-02-08 20:40 +0100 |
| Subject | Re: [PATCH v2 net-next 1/9] sunvnet: make sunvnet common code dynamically loadable |
| Message-ID | <t8GfU-4p7-9@gated-at.bofh.it> |
| In reply to | #1576118 |
From: Shannon Nelson <shannon.nelson@oracle.com>
Date: Tue, 7 Feb 2017 14:12:54 -0800
> +static int __init sunvnet_common_init(void)
> +{
> + pr_info("%s\n", version);
> + return 0;
> +}
> +module_init(sunvnet_common_init);
> +
> +static void __exit sunvnet_common_exit(void)
> +{
> + /* Empty function, just here to fill the exit function pointer
> + * slot. In some combinations of older gcc and newer kernel,
> + * leaving this undefined results in the kernel marking it as a
> + * permanent module; it will show up in lsmod output as [permanent]
> + * and not be unloadable.
> + */
> +}
> +module_exit(sunvnet_common_exit);
> +
This module is just providing infrastructure for other modules.
So skip the init function, and that way you don't need the exit
function either.
The kernel log message when the real sunvnet driver loads is
sufficient, you don't need one here.
[toc] | [prev] | [next] | [standalone]
| From | Shannon Nelson <shannon.nelson@oracle.com> |
|---|---|
| Date | 2017-02-08 23:00 +0100 |
| Subject | Re: [PATCH v2 net-next 1/9] sunvnet: make sunvnet common code dynamically loadable |
| Message-ID | <t8Iro-5Hm-33@gated-at.bofh.it> |
| In reply to | #1576976 |
On 2/8/2017 11:29 AM, David Miller wrote:
> From: Shannon Nelson <shannon.nelson@oracle.com>
> Date: Tue, 7 Feb 2017 14:12:54 -0800
>
>> +static int __init sunvnet_common_init(void)
>> +{
>> + pr_info("%s\n", version);
>> + return 0;
>> +}
>> +module_init(sunvnet_common_init);
>> +
>> +static void __exit sunvnet_common_exit(void)
>> +{
>> + /* Empty function, just here to fill the exit function pointer
>> + * slot. In some combinations of older gcc and newer kernel,
>> + * leaving this undefined results in the kernel marking it as a
>> + * permanent module; it will show up in lsmod output as [permanent]
>> + * and not be unloadable.
>> + */
>> +}
>> +module_exit(sunvnet_common_exit);
>> +
>
> This module is just providing infrastructure for other modules.
>
> So skip the init function, and that way you don't need the exit
> function either.
>
> The kernel log message when the real sunvnet driver loads is
> sufficient, you don't need one here.
>
Sure - thanks,
sln
[toc] | [prev] | [next] | [standalone]
| From | Shannon Nelson <shannon.nelson@oracle.com> |
|---|---|
| Date | 2017-02-07 23:20 +0100 |
| Subject | [PATCH v2 net-next 4/9] sunvnet: add driver stats for ethtool support |
| Message-ID | <t8mhb-fy-15@gated-at.bofh.it> |
| In reply to | #1576113 |
Since we're collecting some stats in the driver code, let's support use
of the ethtool driver stats facility in both sunvnet and ldmvsw.
Signed-off-by: Shannon Nelson <shannon.nelson@oracle.com>
---
drivers/net/ethernet/sun/ldmvsw.c | 63 +++++++++++++++++++++++++++++
drivers/net/ethernet/sun/sunvnet.c | 63 +++++++++++++++++++++++++++++
drivers/net/ethernet/sun/sunvnet_common.c | 2 +
3 files changed, 128 insertions(+), 0 deletions(-)
diff --git a/drivers/net/ethernet/sun/ldmvsw.c b/drivers/net/ethernet/sun/ldmvsw.c
index 335b876..3999fb7 100644
--- a/drivers/net/ethernet/sun/ldmvsw.c
+++ b/drivers/net/ethernet/sun/ldmvsw.c
@@ -80,11 +80,74 @@ static void vsw_set_msglevel(struct net_device *dev, u32 value)
port->vp->msg_enable = value;
}
+static const struct {
+ const char string[ETH_GSTRING_LEN];
+} ethtool_stats_keys[] = {
+ { "rx_packets" },
+ { "tx_packets" },
+ { "rx_bytes" },
+ { "tx_bytes" },
+ { "rx_errors" },
+ { "tx_errors" },
+ { "rx_dropped" },
+ { "tx_dropped" },
+ { "multicast" },
+ { "rx_length_errors" },
+ { "rx_frame_errors" },
+ { "rx_missed_errors" },
+ { "tx_carrier_errors" },
+};
+
+static int vsw_get_sset_count(struct net_device *dev, int sset)
+{
+ switch (sset) {
+ case ETH_SS_STATS:
+ return ARRAY_SIZE(ethtool_stats_keys);
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+static void vsw_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
+{
+ switch (stringset) {
+ case ETH_SS_STATS:
+ memcpy(buf, ðtool_stats_keys, sizeof(ethtool_stats_keys));
+ break;
+ default:
+ WARN_ON(1);
+ break;
+ }
+}
+
+static void vsw_get_ethtool_stats(struct net_device *dev,
+ struct ethtool_stats *estats, u64 *data)
+{
+ int i = 0;
+
+ data[i++] = dev->stats.rx_packets;
+ data[i++] = dev->stats.tx_packets;
+ data[i++] = dev->stats.rx_bytes;
+ data[i++] = dev->stats.tx_bytes;
+ data[i++] = dev->stats.rx_errors;
+ data[i++] = dev->stats.tx_errors;
+ data[i++] = dev->stats.rx_dropped;
+ data[i++] = dev->stats.tx_dropped;
+ data[i++] = dev->stats.multicast;
+ data[i++] = dev->stats.rx_length_errors;
+ data[i++] = dev->stats.rx_frame_errors;
+ data[i++] = dev->stats.rx_missed_errors;
+ data[i++] = dev->stats.tx_carrier_errors;
+}
+
static const struct ethtool_ops vsw_ethtool_ops = {
.get_drvinfo = vsw_get_drvinfo,
.get_msglevel = vsw_get_msglevel,
.set_msglevel = vsw_set_msglevel,
.get_link = ethtool_op_get_link,
+ .get_sset_count = vsw_get_sset_count,
+ .get_strings = vsw_get_strings,
+ .get_ethtool_stats = vsw_get_ethtool_stats,
};
static LIST_HEAD(vnet_list);
diff --git a/drivers/net/ethernet/sun/sunvnet.c b/drivers/net/ethernet/sun/sunvnet.c
index 4cc2571..e225b27 100644
--- a/drivers/net/ethernet/sun/sunvnet.c
+++ b/drivers/net/ethernet/sun/sunvnet.c
@@ -77,11 +77,74 @@ static void vnet_set_msglevel(struct net_device *dev, u32 value)
vp->msg_enable = value;
}
+static const struct {
+ const char string[ETH_GSTRING_LEN];
+} ethtool_stats_keys[] = {
+ { "rx_packets" },
+ { "tx_packets" },
+ { "rx_bytes" },
+ { "tx_bytes" },
+ { "rx_errors" },
+ { "tx_errors" },
+ { "rx_dropped" },
+ { "tx_dropped" },
+ { "multicast" },
+ { "rx_length_errors" },
+ { "rx_frame_errors" },
+ { "rx_missed_errors" },
+ { "tx_carrier_errors" },
+};
+
+static int vnet_get_sset_count(struct net_device *dev, int sset)
+{
+ switch (sset) {
+ case ETH_SS_STATS:
+ return ARRAY_SIZE(ethtool_stats_keys);
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+static void vnet_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
+{
+ switch (stringset) {
+ case ETH_SS_STATS:
+ memcpy(buf, ðtool_stats_keys, sizeof(ethtool_stats_keys));
+ break;
+ default:
+ WARN_ON(1);
+ break;
+ }
+}
+
+static void vnet_get_ethtool_stats(struct net_device *dev,
+ struct ethtool_stats *estats, u64 *data)
+{
+ int i = 0;
+
+ data[i++] = dev->stats.rx_packets;
+ data[i++] = dev->stats.tx_packets;
+ data[i++] = dev->stats.rx_bytes;
+ data[i++] = dev->stats.tx_bytes;
+ data[i++] = dev->stats.rx_errors;
+ data[i++] = dev->stats.tx_errors;
+ data[i++] = dev->stats.rx_dropped;
+ data[i++] = dev->stats.tx_dropped;
+ data[i++] = dev->stats.multicast;
+ data[i++] = dev->stats.rx_length_errors;
+ data[i++] = dev->stats.rx_frame_errors;
+ data[i++] = dev->stats.rx_missed_errors;
+ data[i++] = dev->stats.tx_carrier_errors;
+}
+
static const struct ethtool_ops vnet_ethtool_ops = {
.get_drvinfo = vnet_get_drvinfo,
.get_msglevel = vnet_get_msglevel,
.set_msglevel = vnet_set_msglevel,
.get_link = ethtool_op_get_link,
+ .get_sset_count = vnet_get_sset_count,
+ .get_strings = vnet_get_strings,
+ .get_ethtool_stats = vnet_get_ethtool_stats,
};
static LIST_HEAD(vnet_list);
diff --git a/drivers/net/ethernet/sun/sunvnet_common.c b/drivers/net/ethernet/sun/sunvnet_common.c
index add22d4..82273e6 100644
--- a/drivers/net/ethernet/sun/sunvnet_common.c
+++ b/drivers/net/ethernet/sun/sunvnet_common.c
@@ -433,6 +433,8 @@ static int vnet_rx_one(struct vnet_port *port, struct vio_net_desc *desc)
skb->ip_summed = port->switch_port ? CHECKSUM_NONE : CHECKSUM_PARTIAL;
+ if (unlikely(is_multicast_ether_addr(eth_hdr(skb)->h_dest)))
+ dev->stats.multicast++;
dev->stats.rx_packets++;
dev->stats.rx_bytes += len;
napi_gro_receive(&port->napi, skb);
--
1.7.1
[toc] | [prev] | [next] | [standalone]
| From | Shannon Nelson <shannon.nelson@oracle.com> |
|---|---|
| Date | 2017-02-07 23:20 +0100 |
| Subject | [PATCH v2 net-next 9/9] ldmvsw: disable tso and gso for bridge operations |
| Message-ID | <t8mhc-fy-19@gated-at.bofh.it> |
| In reply to | #1576113 |
The ldmvsw driver is specifically for supporting the ldom virtual
networking by running in the primary ldom and using the LDC to connect
the remaining ldoms to the outside world via a bridge. With TSO and GSO
supported while connected the bridge, things tend to misbehave as seen
in our case by delayed packets, enough to begin triggering retransmits
and affecting overall throughput. By turning off advertised support for
TSO and GSO we restore stable traffic flow through the bridge.
Orabug: 23293104
Signed-off-by: Shannon Nelson <shannon.nelson@oracle.com>
---
drivers/net/ethernet/sun/ldmvsw.c | 5 ++---
drivers/net/ethernet/sun/sunvnet_common.c | 3 ++-
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/sun/ldmvsw.c b/drivers/net/ethernet/sun/ldmvsw.c
index 3ef5c08..8e1ecfb 100644
--- a/drivers/net/ethernet/sun/ldmvsw.c
+++ b/drivers/net/ethernet/sun/ldmvsw.c
@@ -297,8 +297,7 @@ static void vsw_poll_controller(struct net_device *dev)
dev->ethtool_ops = &vsw_ethtool_ops;
dev->watchdog_timeo = VSW_TX_TIMEOUT;
- dev->hw_features = NETIF_F_TSO | NETIF_F_GSO | NETIF_F_GSO_SOFTWARE |
- NETIF_F_HW_CSUM | NETIF_F_SG;
+ dev->hw_features = NETIF_F_HW_CSUM | NETIF_F_SG;
dev->features = dev->hw_features;
/* MTU range: 68 - 65535 */
@@ -383,7 +382,7 @@ static int vsw_port_probe(struct vio_dev *vdev, const struct vio_device_id *id)
port->vp = vp;
port->dev = dev;
port->switch_port = 1;
- port->tso = true;
+ port->tso = false; /* no tso in vsw, misbehaves in bridge */
port->tsolen = 0;
/* Mark the port as belonging to ldmvsw which directs the
diff --git a/drivers/net/ethernet/sun/sunvnet_common.c b/drivers/net/ethernet/sun/sunvnet_common.c
index 9384db0..1a9bc56 100644
--- a/drivers/net/ethernet/sun/sunvnet_common.c
+++ b/drivers/net/ethernet/sun/sunvnet_common.c
@@ -210,6 +210,7 @@ static int handle_attr_info(struct vio_driver_state *vio,
} else {
pkt->cflags &= ~VNET_LSO_IPV4_CAPAB;
pkt->ipv4_lso_maxlen = 0;
+ port->tsolen = 0;
}
/* for version >= 1.6, ACK packet mode we support */
@@ -1661,7 +1662,7 @@ static void vnet_port_reset(struct vnet_port *port)
del_timer(&port->clean_timer);
sunvnet_port_free_tx_bufs_common(port);
port->rmtu = 0;
- port->tso = true;
+ port->tso = (port->vsw == 0); /* no tso in vsw, misbehaves in bridge */
port->tsolen = 0;
}
--
1.7.1
[toc] | [prev] | [next] | [standalone]
| From | Shannon Nelson <shannon.nelson@oracle.com> |
|---|---|
| Date | 2017-02-07 23:30 +0100 |
| Subject | [PATCH v2 net-next 7/9] sunvnet: remove extra rcu_read_unlocks |
| Message-ID | <t8mqS-iJ-15@gated-at.bofh.it> |
| In reply to | #1576113 |
The RCU read lock is grabbed first thing in sunvnet_start_xmit_common()
so it always needs to be released. This removes the conditional release
in the dropped packet error path and removes a couple of superfluous
calls in the middle of the code.
Reported-by: Bijan Mottahedeh <bijan.mottahedeh@oracle.com>
Signed-off-by: Shannon Nelson <shannon.nelson@oracle.com>
---
drivers/net/ethernet/sun/sunvnet_common.c | 8 ++------
1 files changed, 2 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/sun/sunvnet_common.c b/drivers/net/ethernet/sun/sunvnet_common.c
index d2aed2c..9384db0 100644
--- a/drivers/net/ethernet/sun/sunvnet_common.c
+++ b/drivers/net/ethernet/sun/sunvnet_common.c
@@ -1279,10 +1279,8 @@ int sunvnet_start_xmit_common(struct sk_buff *skb, struct net_device *dev,
rcu_read_lock();
port = vnet_tx_port(skb, dev);
- if (unlikely(!port)) {
- rcu_read_unlock();
+ if (unlikely(!port))
goto out_dropped;
- }
if (skb_is_gso(skb) && skb->len > port->tsolen) {
err = vnet_handle_offloads(port, skb, vnet_tx_port);
@@ -1307,7 +1305,6 @@ int sunvnet_start_xmit_common(struct sk_buff *skb, struct net_device *dev,
fl4.saddr = ip_hdr(skb)->saddr;
rt = ip_route_output_key(dev_net(dev), &fl4);
- rcu_read_unlock();
if (!IS_ERR(rt)) {
skb_dst_set(skb, &rt->dst);
icmp_send(skb, ICMP_DEST_UNREACH,
@@ -1467,8 +1464,7 @@ int sunvnet_start_xmit_common(struct sk_buff *skb, struct net_device *dev,
jiffies + VNET_CLEAN_TIMEOUT);
else if (port)
del_timer(&port->clean_timer);
- if (port)
- rcu_read_unlock();
+ rcu_read_unlock();
if (skb)
dev_kfree_skb(skb);
vnet_free_skbs(freeskbs);
--
1.7.1
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web