* [PATCH 1/3] net: tilegx driver bugfix (be explicit about percpu queue number)
2012-07-01 18:43 [PATCH 0/3] net: various tilegx networking fixes Chris Metcalf
@ 2012-07-01 18:43 ` Chris Metcalf
2012-07-11 18:08 ` [PATCH 2/3] tilegx net driver: handle payload data not in frags Chris Metcalf
` (2 subsequent siblings)
3 siblings, 0 replies; 6+ messages in thread
From: Chris Metcalf @ 2012-07-01 18:43 UTC (permalink / raw)
To: David S. Miller, netdev, linux-kernel
Avoid packets belonging to queue/cpu A trying to transmit on cpu B.
Signed-off-by: Chris Metcalf <cmetcalf@tilera.com>
---
drivers/net/ethernet/tile/tilegx.c | 23 +++++++++++++++--------
1 file changed, 15 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ethernet/tile/tilegx.c b/drivers/net/ethernet/tile/tilegx.c
index 83b4b38..c7bde28 100644
--- a/drivers/net/ethernet/tile/tilegx.c
+++ b/drivers/net/ethernet/tile/tilegx.c
@@ -123,6 +123,7 @@ struct tile_net_comps {
/* The transmit wake timer for a given cpu and echannel. */
struct tile_net_tx_wake {
+ int tx_queue_idx;
struct hrtimer timer;
struct net_device *dev;
};
@@ -573,12 +574,14 @@ static void add_comp(gxio_mpipe_equeue_t *equeue,
comps->comp_next++;
}
-static void tile_net_schedule_tx_wake_timer(struct net_device *dev)
+static void tile_net_schedule_tx_wake_timer(struct net_device *dev,
+ int tx_queue_idx)
{
- struct tile_net_info *info = &__get_cpu_var(per_cpu_info);
+ struct tile_net_info *info = &per_cpu(per_cpu_info, tx_queue_idx);
struct tile_net_priv *priv = netdev_priv(dev);
+ struct tile_net_tx_wake *tx_wake = &info->tx_wake[priv->echannel];
- hrtimer_start(&info->tx_wake[priv->echannel].timer,
+ hrtimer_start(&tx_wake->timer,
ktime_set(0, TX_TIMER_DELAY_USEC * 1000UL),
HRTIMER_MODE_REL_PINNED);
}
@@ -587,7 +590,7 @@ static enum hrtimer_restart tile_net_handle_tx_wake_timer(struct hrtimer *t)
{
struct tile_net_tx_wake *tx_wake =
container_of(t, struct tile_net_tx_wake, timer);
- netif_wake_subqueue(tx_wake->dev, smp_processor_id());
+ netif_wake_subqueue(tx_wake->dev, tx_wake->tx_queue_idx);
return HRTIMER_NORESTART;
}
@@ -1218,6 +1221,7 @@ static int tile_net_open(struct net_device *dev)
hrtimer_init(&tx_wake->timer, CLOCK_MONOTONIC,
HRTIMER_MODE_REL);
+ tx_wake->tx_queue_idx = cpu;
tx_wake->timer.function = tile_net_handle_tx_wake_timer;
tx_wake->dev = dev;
}
@@ -1291,6 +1295,7 @@ static inline void *tile_net_frag_buf(skb_frag_t *f)
* stop the queue and schedule the tx_wake timer.
*/
static s64 tile_net_equeue_try_reserve(struct net_device *dev,
+ int tx_queue_idx,
struct tile_net_comps *comps,
gxio_mpipe_equeue_t *equeue,
int num_edescs)
@@ -1313,8 +1318,8 @@ static s64 tile_net_equeue_try_reserve(struct net_device *dev,
}
/* Still nothing; give up and stop the queue for a short while. */
- netif_stop_subqueue(dev, smp_processor_id());
- tile_net_schedule_tx_wake_timer(dev);
+ netif_stop_subqueue(dev, tx_queue_idx);
+ tile_net_schedule_tx_wake_timer(dev, tx_queue_idx);
return -1;
}
@@ -1580,7 +1585,8 @@ static int tile_net_tx_tso(struct sk_buff *skb, struct net_device *dev)
local_irq_save(irqflags);
/* Try to acquire a completion entry and an egress slot. */
- slot = tile_net_equeue_try_reserve(dev, comps, equeue, num_edescs);
+ slot = tile_net_equeue_try_reserve(dev, skb->queue_mapping, comps,
+ equeue, num_edescs);
if (slot < 0) {
local_irq_restore(irqflags);
return NETDEV_TX_BUSY;
@@ -1674,7 +1680,8 @@ static int tile_net_tx(struct sk_buff *skb, struct net_device *dev)
local_irq_save(irqflags);
/* Try to acquire a completion entry and an egress slot. */
- slot = tile_net_equeue_try_reserve(dev, comps, equeue, num_edescs);
+ slot = tile_net_equeue_try_reserve(dev, skb->queue_mapping, comps,
+ equeue, num_edescs);
if (slot < 0) {
local_irq_restore(irqflags);
return NETDEV_TX_BUSY;
--
1.7.10.3
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH 2/3] tilegx net driver: handle payload data not in frags
2012-07-01 18:43 [PATCH 0/3] net: various tilegx networking fixes Chris Metcalf
2012-07-01 18:43 ` [PATCH 1/3] net: tilegx driver bugfix (be explicit about percpu queue number) Chris Metcalf
@ 2012-07-11 18:08 ` Chris Metcalf
2012-07-18 16:23 ` [PATCH 3/3] tilegx net: use eth_hw_addr_random(), not random_ether_addr() Chris Metcalf
2012-07-18 16:47 ` [PATCH 0/3] net: various tilegx networking fixes David Miller
3 siblings, 0 replies; 6+ messages in thread
From: Chris Metcalf @ 2012-07-11 18:08 UTC (permalink / raw)
To: David S. Miller, netdev, linux-kernel
The original driver implementation assumed that for TSO, all the
payload data would be in the frags. This isn't always true; change
the driver to support payload data at skb->data between
"skb_transport_offset(skb) + tcp_hdrlen(skb)" and "skb->hdr_len",
followed by the data in the frags.
Signed-off-by: Chris Metcalf <cmetcalf@tilera.com>
---
drivers/net/ethernet/tile/tilegx.c | 36 ++++++++++++++++++------------------
1 file changed, 18 insertions(+), 18 deletions(-)
diff --git a/drivers/net/ethernet/tile/tilegx.c b/drivers/net/ethernet/tile/tilegx.c
index c7bde28..f78effc 100644
--- a/drivers/net/ethernet/tile/tilegx.c
+++ b/drivers/net/ethernet/tile/tilegx.c
@@ -1333,11 +1333,12 @@ static s64 tile_net_equeue_try_reserve(struct net_device *dev,
static int tso_count_edescs(struct sk_buff *skb)
{
struct skb_shared_info *sh = skb_shinfo(skb);
- unsigned int data_len = skb->data_len;
+ unsigned int sh_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
+ unsigned int data_len = skb->data_len + skb->hdr_len - sh_len;
unsigned int p_len = sh->gso_size;
long f_id = -1; /* id of the current fragment */
- long f_size = -1; /* size of the current fragment */
- long f_used = -1; /* bytes used from the current fragment */
+ long f_size = skb->hdr_len; /* size of the current fragment */
+ long f_used = sh_len; /* bytes used from the current fragment */
long n; /* size of the current piece of payload */
int num_edescs = 0;
int segment;
@@ -1382,13 +1383,14 @@ static void tso_headers_prepare(struct sk_buff *skb, unsigned char *headers,
struct skb_shared_info *sh = skb_shinfo(skb);
struct iphdr *ih;
struct tcphdr *th;
- unsigned int data_len = skb->data_len;
+ unsigned int sh_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
+ unsigned int data_len = skb->data_len + skb->hdr_len - sh_len;
unsigned char *data = skb->data;
- unsigned int ih_off, th_off, sh_len, p_len;
+ unsigned int ih_off, th_off, p_len;
unsigned int isum_seed, tsum_seed, id, seq;
long f_id = -1; /* id of the current fragment */
- long f_size = -1; /* size of the current fragment */
- long f_used = -1; /* bytes used from the current fragment */
+ long f_size = skb->hdr_len; /* size of the current fragment */
+ long f_used = sh_len; /* bytes used from the current fragment */
long n; /* size of the current piece of payload */
int segment;
@@ -1397,14 +1399,13 @@ static void tso_headers_prepare(struct sk_buff *skb, unsigned char *headers,
th = tcp_hdr(skb);
ih_off = skb_network_offset(skb);
th_off = skb_transport_offset(skb);
- sh_len = th_off + tcp_hdrlen(skb);
p_len = sh->gso_size;
/* Set up seed values for IP and TCP csum and initialize id and seq. */
isum_seed = ((0xFFFF - ih->check) +
(0xFFFF - ih->tot_len) +
(0xFFFF - ih->id));
- tsum_seed = th->check + (0xFFFF ^ htons(skb->len));
+ tsum_seed = th->check + (0xFFFF ^ htons(sh_len + data_len));
id = ntohs(ih->id);
seq = ntohl(th->seq);
@@ -1476,21 +1477,22 @@ static void tso_egress(struct net_device *dev, gxio_mpipe_equeue_t *equeue,
{
struct tile_net_priv *priv = netdev_priv(dev);
struct skb_shared_info *sh = skb_shinfo(skb);
- unsigned int data_len = skb->data_len;
+ unsigned int sh_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
+ unsigned int data_len = skb->data_len + skb->hdr_len - sh_len;
unsigned int p_len = sh->gso_size;
gxio_mpipe_edesc_t edesc_head = { { 0 } };
gxio_mpipe_edesc_t edesc_body = { { 0 } };
long f_id = -1; /* id of the current fragment */
- long f_size = -1; /* size of the current fragment */
- long f_used = -1; /* bytes used from the current fragment */
+ long f_size = skb->hdr_len; /* size of the current fragment */
+ long f_used = sh_len; /* bytes used from the current fragment */
+ void *f_data = skb->data;
long n; /* size of the current piece of payload */
unsigned long tx_packets = 0, tx_bytes = 0;
- unsigned int csum_start, sh_len;
+ unsigned int csum_start;
int segment;
/* Prepare to egress the headers: set up header edesc. */
csum_start = skb_checksum_start_offset(skb);
- sh_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
edesc_head.csum = 1;
edesc_head.csum_start = csum_start;
edesc_head.csum_dest = csum_start + skb->csum_offset;
@@ -1502,7 +1504,6 @@ static void tso_egress(struct net_device *dev, gxio_mpipe_equeue_t *equeue,
/* Egress all the edescs. */
for (segment = 0; segment < sh->gso_segs; segment++) {
- void *va;
unsigned char *buf;
unsigned int p_used = 0;
@@ -1521,10 +1522,9 @@ static void tso_egress(struct net_device *dev, gxio_mpipe_equeue_t *equeue,
f_id++;
f_size = sh->frags[f_id].size;
f_used = 0;
+ f_data = tile_net_frag_buf(&sh->frags[f_id]);
}
- va = tile_net_frag_buf(&sh->frags[f_id]) + f_used;
-
/* Use bytes from the current fragment. */
n = p_len - p_used;
if (n > f_size - f_used)
@@ -1533,7 +1533,7 @@ static void tso_egress(struct net_device *dev, gxio_mpipe_equeue_t *equeue,
p_used += n;
/* Egress a piece of the payload. */
- edesc_body.va = va_to_tile_io_addr(va);
+ edesc_body.va = va_to_tile_io_addr(f_data) + f_used;
edesc_body.xfer_size = n;
edesc_body.bound = !(p_used < p_len);
gxio_mpipe_equeue_put_at(equeue, edesc_body, slot);
--
1.7.10.3
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH 3/3] tilegx net: use eth_hw_addr_random(), not random_ether_addr()
2012-07-01 18:43 [PATCH 0/3] net: various tilegx networking fixes Chris Metcalf
2012-07-01 18:43 ` [PATCH 1/3] net: tilegx driver bugfix (be explicit about percpu queue number) Chris Metcalf
2012-07-11 18:08 ` [PATCH 2/3] tilegx net driver: handle payload data not in frags Chris Metcalf
@ 2012-07-18 16:23 ` Chris Metcalf
2012-07-18 16:47 ` [PATCH 0/3] net: various tilegx networking fixes David Miller
3 siblings, 0 replies; 6+ messages in thread
From: Chris Metcalf @ 2012-07-18 16:23 UTC (permalink / raw)
To: David S. Miller, netdev, linux-kernel
Signed-off-by: Chris Metcalf <cmetcalf@tilera.com>
---
drivers/net/ethernet/tile/tilegx.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/tile/tilegx.c b/drivers/net/ethernet/tile/tilegx.c
index f78effc..4e2a162 100644
--- a/drivers/net/ethernet/tile/tilegx.c
+++ b/drivers/net/ethernet/tile/tilegx.c
@@ -1851,7 +1851,7 @@ static void tile_net_dev_init(const char *name, const uint8_t *mac)
memcpy(dev->dev_addr, mac, 6);
dev->addr_len = 6;
} else {
- random_ether_addr(dev->dev_addr);
+ eth_hw_addr_random(dev);
}
/* Register the network device. */
--
1.7.10.3
^ permalink raw reply related [flat|nested] 6+ messages in thread* Re: [PATCH 0/3] net: various tilegx networking fixes
2012-07-01 18:43 [PATCH 0/3] net: various tilegx networking fixes Chris Metcalf
` (2 preceding siblings ...)
2012-07-18 16:23 ` [PATCH 3/3] tilegx net: use eth_hw_addr_random(), not random_ether_addr() Chris Metcalf
@ 2012-07-18 16:47 ` David Miller
3 siblings, 0 replies; 6+ messages in thread
From: David Miller @ 2012-07-18 16:47 UTC (permalink / raw)
To: cmetcalf; +Cc: netdev, linux-kernel
Please don't post patches like you did here.
The big problem is that you use the dates of your commit in
the email, that breaks everything.
It makes the patches appear out of order in patchwork, which make
more work for me.
Please repost these patches, and tell git-am or whatever tool you use
to not use the commit date in the outgoing emails.
THanks.
^ permalink raw reply [flat|nested] 6+ messages in thread