* [PATCH net-next 07/11] sfc: Separate out queue-empty check from efx_nic_may_push_tx_desc()
From: Ben Hutchings @ 2013-09-21 18:35 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
In-Reply-To: <1379788283.1681.34.camel@bwh-desktop.uk.level5networks.com>
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
drivers/net/ethernet/sfc/nic.h | 28 ++++++++++++++++++++++------
1 file changed, 22 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/sfc/nic.h b/drivers/net/ethernet/sfc/nic.h
index a6e4336..53f8cf6 100644
--- a/drivers/net/ethernet/sfc/nic.h
+++ b/drivers/net/ethernet/sfc/nic.h
@@ -71,6 +71,26 @@ efx_tx_desc(struct efx_tx_queue *tx_queue, unsigned int index)
return ((efx_qword_t *) (tx_queue->txd.buf.addr)) + index;
}
+/* Report whether the NIC considers this TX queue empty, given the
+ * write_count used for the last doorbell push. May return false
+ * negative.
+ */
+static inline bool __efx_nic_tx_is_empty(struct efx_tx_queue *tx_queue,
+ unsigned int write_count)
+{
+ unsigned int empty_read_count = ACCESS_ONCE(tx_queue->empty_read_count);
+
+ if (empty_read_count == 0)
+ return false;
+
+ return ((empty_read_count ^ write_count) & ~EFX_EMPTY_COUNT_VALID) == 0;
+}
+
+static inline bool efx_nic_tx_is_empty(struct efx_tx_queue *tx_queue)
+{
+ return __efx_nic_tx_is_empty(tx_queue, tx_queue->write_count);
+}
+
/* Decide whether to push a TX descriptor to the NIC vs merely writing
* the doorbell. This can reduce latency when we are adding a single
* descriptor to an empty queue, but is otherwise pointless. Further,
@@ -80,14 +100,10 @@ efx_tx_desc(struct efx_tx_queue *tx_queue, unsigned int index)
static inline bool efx_nic_may_push_tx_desc(struct efx_tx_queue *tx_queue,
unsigned int write_count)
{
- unsigned empty_read_count = ACCESS_ONCE(tx_queue->empty_read_count);
-
- if (empty_read_count == 0)
- return false;
+ bool was_empty = __efx_nic_tx_is_empty(tx_queue, write_count);
tx_queue->empty_read_count = 0;
- return ((empty_read_count ^ write_count) & ~EFX_EMPTY_COUNT_VALID) == 0
- && tx_queue->write_count - write_count == 1;
+ return was_empty && tx_queue->write_count - write_count == 1;
}
/* Returns a pointer to the specified descriptor in the RX descriptor queue */
--
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply related
* [PATCH net-next 08/11] sfc: Introduce inline functions to simplify TX insertion
From: Ben Hutchings @ 2013-09-21 18:35 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
In-Reply-To: <1379788283.1681.34.camel@bwh-desktop.uk.level5networks.com>
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
drivers/net/ethernet/sfc/tx.c | 53 +++++++++++++++++++++++++++----------------
1 file changed, 33 insertions(+), 20 deletions(-)
diff --git a/drivers/net/ethernet/sfc/tx.c b/drivers/net/ethernet/sfc/tx.c
index 8754347..6cecda3 100644
--- a/drivers/net/ethernet/sfc/tx.c
+++ b/drivers/net/ethernet/sfc/tx.c
@@ -33,6 +33,31 @@ unsigned int efx_piobuf_size __read_mostly = EFX_PIOBUF_SIZE_DEF;
#endif /* EFX_USE_PIO */
+static inline unsigned int
+efx_tx_queue_get_insert_index(const struct efx_tx_queue *tx_queue)
+{
+ return tx_queue->insert_count & tx_queue->ptr_mask;
+}
+
+static inline struct efx_tx_buffer *
+__efx_tx_queue_get_insert_buffer(const struct efx_tx_queue *tx_queue)
+{
+ return &tx_queue->buffer[efx_tx_queue_get_insert_index(tx_queue)];
+}
+
+static inline struct efx_tx_buffer *
+efx_tx_queue_get_insert_buffer(const struct efx_tx_queue *tx_queue)
+{
+ struct efx_tx_buffer *buffer =
+ __efx_tx_queue_get_insert_buffer(tx_queue);
+
+ EFX_BUG_ON_PARANOID(buffer->len);
+ EFX_BUG_ON_PARANOID(buffer->flags);
+ EFX_BUG_ON_PARANOID(buffer->unmap_len);
+
+ return buffer;
+}
+
static void efx_dequeue_buffer(struct efx_tx_queue *tx_queue,
struct efx_tx_buffer *buffer,
unsigned int *pkts_compl,
@@ -180,7 +205,7 @@ netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb)
struct device *dma_dev = &efx->pci_dev->dev;
struct efx_tx_buffer *buffer;
skb_frag_t *fragment;
- unsigned int len, unmap_len = 0, insert_ptr;
+ unsigned int len, unmap_len = 0;
dma_addr_t dma_addr, unmap_addr = 0;
unsigned int dma_len;
unsigned short dma_flags;
@@ -221,11 +246,7 @@ netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb)
/* Add to TX queue, splitting across DMA boundaries */
do {
- insert_ptr = tx_queue->insert_count & tx_queue->ptr_mask;
- buffer = &tx_queue->buffer[insert_ptr];
- EFX_BUG_ON_PARANOID(buffer->flags);
- EFX_BUG_ON_PARANOID(buffer->len);
- EFX_BUG_ON_PARANOID(buffer->unmap_len);
+ buffer = efx_tx_queue_get_insert_buffer(tx_queue);
dma_len = efx_max_tx_len(efx, dma_addr);
if (likely(dma_len >= len))
@@ -283,8 +304,7 @@ netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb)
while (tx_queue->insert_count != tx_queue->write_count) {
unsigned int pkts_compl = 0, bytes_compl = 0;
--tx_queue->insert_count;
- insert_ptr = tx_queue->insert_count & tx_queue->ptr_mask;
- buffer = &tx_queue->buffer[insert_ptr];
+ buffer = __efx_tx_queue_get_insert_buffer(tx_queue);
efx_dequeue_buffer(tx_queue, buffer, &pkts_compl, &bytes_compl);
}
@@ -755,23 +775,18 @@ static void efx_tx_queue_insert(struct efx_tx_queue *tx_queue,
{
struct efx_tx_buffer *buffer;
struct efx_nic *efx = tx_queue->efx;
- unsigned dma_len, insert_ptr;
+ unsigned dma_len;
EFX_BUG_ON_PARANOID(len <= 0);
while (1) {
- insert_ptr = tx_queue->insert_count & tx_queue->ptr_mask;
- buffer = &tx_queue->buffer[insert_ptr];
+ buffer = efx_tx_queue_get_insert_buffer(tx_queue);
++tx_queue->insert_count;
EFX_BUG_ON_PARANOID(tx_queue->insert_count -
tx_queue->read_count >=
efx->txq_entries);
- EFX_BUG_ON_PARANOID(buffer->len);
- EFX_BUG_ON_PARANOID(buffer->unmap_len);
- EFX_BUG_ON_PARANOID(buffer->flags);
-
buffer->dma_addr = dma_addr;
dma_len = efx_max_tx_len(efx, dma_addr);
@@ -832,8 +847,7 @@ static void efx_enqueue_unwind(struct efx_tx_queue *tx_queue)
/* Work backwards until we hit the original insert pointer value */
while (tx_queue->insert_count != tx_queue->write_count) {
--tx_queue->insert_count;
- buffer = &tx_queue->buffer[tx_queue->insert_count &
- tx_queue->ptr_mask];
+ buffer = __efx_tx_queue_get_insert_buffer(tx_queue);
efx_dequeue_buffer(tx_queue, buffer, NULL, NULL);
}
}
@@ -978,7 +992,7 @@ static int tso_start_new_packet(struct efx_tx_queue *tx_queue,
struct tso_state *st)
{
struct efx_tx_buffer *buffer =
- &tx_queue->buffer[tx_queue->insert_count & tx_queue->ptr_mask];
+ efx_tx_queue_get_insert_buffer(tx_queue);
bool is_last = st->out_len <= skb_shinfo(skb)->gso_size;
u8 tcp_flags_clear;
@@ -1048,8 +1062,7 @@ static int tso_start_new_packet(struct efx_tx_queue *tx_queue,
/* We mapped the headers in tso_start(). Unmap them
* when the last segment is completed.
*/
- buffer = &tx_queue->buffer[tx_queue->insert_count &
- tx_queue->ptr_mask];
+ buffer = efx_tx_queue_get_insert_buffer(tx_queue);
buffer->dma_addr = st->header_dma_addr;
buffer->len = st->header_len;
if (is_last) {
--
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply related
* [PATCH net-next 09/11] sfc: Use TX PIO for sufficiently small packets
From: Ben Hutchings @ 2013-09-21 18:35 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
In-Reply-To: <1379788283.1681.34.camel@bwh-desktop.uk.level5networks.com>
From: Jon Cooper <jcooper@solarflare.com>
Sufficiently small linear packets can be copied into the PIO buffer
with a single call to memcpy_toio(). Non-linear packets require an
intermediate cache-line-sized buffer.
[bwh: I wrote the first version of this, but Jon did the hard work to
handle non-linear packets.]
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
drivers/net/ethernet/sfc/ef10_regs.h | 1 +
drivers/net/ethernet/sfc/ethtool.c | 1 +
drivers/net/ethernet/sfc/net_driver.h | 2 +
drivers/net/ethernet/sfc/tx.c | 151 ++++++++++++++++++++++++++++++++++
4 files changed, 155 insertions(+)
diff --git a/drivers/net/ethernet/sfc/ef10_regs.h b/drivers/net/ethernet/sfc/ef10_regs.h
index b3f4e37..207ac9a 100644
--- a/drivers/net/ethernet/sfc/ef10_regs.h
+++ b/drivers/net/ethernet/sfc/ef10_regs.h
@@ -315,6 +315,7 @@
#define ESF_DZ_TX_PIO_TYPE_WIDTH 1
#define ESF_DZ_TX_PIO_OPT_LBN 60
#define ESF_DZ_TX_PIO_OPT_WIDTH 3
+#define ESE_DZ_TX_OPTION_DESC_PIO 1
#define ESF_DZ_TX_PIO_CONT_LBN 59
#define ESF_DZ_TX_PIO_CONT_WIDTH 1
#define ESF_DZ_TX_PIO_BYTE_CNT_LBN 32
diff --git a/drivers/net/ethernet/sfc/ethtool.c b/drivers/net/ethernet/sfc/ethtool.c
index c8dc407..1f529fa 100644
--- a/drivers/net/ethernet/sfc/ethtool.c
+++ b/drivers/net/ethernet/sfc/ethtool.c
@@ -70,6 +70,7 @@ static const struct efx_sw_stat_desc efx_sw_stat_desc[] = {
EFX_ETHTOOL_UINT_TXQ_STAT(tso_long_headers),
EFX_ETHTOOL_UINT_TXQ_STAT(tso_packets),
EFX_ETHTOOL_UINT_TXQ_STAT(pushes),
+ EFX_ETHTOOL_UINT_TXQ_STAT(pio_packets),
EFX_ETHTOOL_ATOMIC_NIC_ERROR_STAT(rx_reset),
EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_tobe_disc),
EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_ip_hdr_chksum_err),
diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h
index 6febecc..aac22a1 100644
--- a/drivers/net/ethernet/sfc/net_driver.h
+++ b/drivers/net/ethernet/sfc/net_driver.h
@@ -212,6 +212,7 @@ struct efx_tx_buffer {
* blocks
* @tso_packets: Number of packets via the TSO xmit path
* @pushes: Number of times the TX push feature has been used
+ * @pio_packets: Number of times the TX PIO feature has been used
* @empty_read_count: If the completion path has seen the queue as empty
* and the transmission path has not yet checked this, the value of
* @read_count bitwise-added to %EFX_EMPTY_COUNT_VALID; otherwise 0.
@@ -243,6 +244,7 @@ struct efx_tx_queue {
unsigned int tso_long_headers;
unsigned int tso_packets;
unsigned int pushes;
+ unsigned int pio_packets;
/* Members shared between paths and sometimes updated */
unsigned int empty_read_count ____cacheline_aligned_in_smp;
diff --git a/drivers/net/ethernet/sfc/tx.c b/drivers/net/ethernet/sfc/tx.c
index 6cecda3..282692c 100644
--- a/drivers/net/ethernet/sfc/tx.c
+++ b/drivers/net/ethernet/sfc/tx.c
@@ -183,6 +183,145 @@ static void efx_tx_maybe_stop_queue(struct efx_tx_queue *txq1)
}
}
+#ifdef EFX_USE_PIO
+
+struct efx_short_copy_buffer {
+ int used;
+ u8 buf[L1_CACHE_BYTES];
+};
+
+/* Copy to PIO, respecting that writes to PIO buffers must be dword aligned.
+ * Advances piobuf pointer. Leaves additional data in the copy buffer.
+ */
+static void efx_memcpy_toio_aligned(struct efx_nic *efx, u8 __iomem **piobuf,
+ u8 *data, int len,
+ struct efx_short_copy_buffer *copy_buf)
+{
+ int block_len = len & ~(sizeof(copy_buf->buf) - 1);
+
+ memcpy_toio(*piobuf, data, block_len);
+ *piobuf += block_len;
+ len -= block_len;
+
+ if (len) {
+ data += block_len;
+ BUG_ON(copy_buf->used);
+ BUG_ON(len > sizeof(copy_buf->buf));
+ memcpy(copy_buf->buf, data, len);
+ copy_buf->used = len;
+ }
+}
+
+/* Copy to PIO, respecting dword alignment, popping data from copy buffer first.
+ * Advances piobuf pointer. Leaves additional data in the copy buffer.
+ */
+static void efx_memcpy_toio_aligned_cb(struct efx_nic *efx, u8 __iomem **piobuf,
+ u8 *data, int len,
+ struct efx_short_copy_buffer *copy_buf)
+{
+ if (copy_buf->used) {
+ /* if the copy buffer is partially full, fill it up and write */
+ int copy_to_buf =
+ min_t(int, sizeof(copy_buf->buf) - copy_buf->used, len);
+
+ memcpy(copy_buf->buf + copy_buf->used, data, copy_to_buf);
+ copy_buf->used += copy_to_buf;
+
+ /* if we didn't fill it up then we're done for now */
+ if (copy_buf->used < sizeof(copy_buf->buf))
+ return;
+
+ memcpy_toio(*piobuf, copy_buf->buf, sizeof(copy_buf->buf));
+ *piobuf += sizeof(copy_buf->buf);
+ data += copy_to_buf;
+ len -= copy_to_buf;
+ copy_buf->used = 0;
+ }
+
+ efx_memcpy_toio_aligned(efx, piobuf, data, len, copy_buf);
+}
+
+static void efx_flush_copy_buffer(struct efx_nic *efx, u8 __iomem *piobuf,
+ struct efx_short_copy_buffer *copy_buf)
+{
+ /* if there's anything in it, write the whole buffer, including junk */
+ if (copy_buf->used)
+ memcpy_toio(piobuf, copy_buf->buf, sizeof(copy_buf->buf));
+}
+
+/* Traverse skb structure and copy fragments in to PIO buffer.
+ * Advances piobuf pointer.
+ */
+static void efx_skb_copy_bits_to_pio(struct efx_nic *efx, struct sk_buff *skb,
+ u8 __iomem **piobuf,
+ struct efx_short_copy_buffer *copy_buf)
+{
+ int i;
+
+ efx_memcpy_toio_aligned(efx, piobuf, skb->data, skb_headlen(skb),
+ copy_buf);
+
+ for (i = 0; i < skb_shinfo(skb)->nr_frags; ++i) {
+ skb_frag_t *f = &skb_shinfo(skb)->frags[i];
+ u8 *vaddr;
+
+ vaddr = kmap_atomic(skb_frag_page(f));
+
+ efx_memcpy_toio_aligned_cb(efx, piobuf, vaddr + f->page_offset,
+ skb_frag_size(f), copy_buf);
+ kunmap_atomic(vaddr);
+ }
+
+ EFX_BUG_ON_PARANOID(skb_shinfo(skb)->frag_list);
+}
+
+static struct efx_tx_buffer *
+efx_enqueue_skb_pio(struct efx_tx_queue *tx_queue, struct sk_buff *skb)
+{
+ struct efx_tx_buffer *buffer =
+ efx_tx_queue_get_insert_buffer(tx_queue);
+ u8 __iomem *piobuf = tx_queue->piobuf;
+
+ /* Copy to PIO buffer. Ensure the writes are padded to the end
+ * of a cache line, as this is required for write-combining to be
+ * effective on at least x86.
+ */
+
+ if (skb_shinfo(skb)->nr_frags) {
+ /* The size of the copy buffer will ensure all writes
+ * are the size of a cache line.
+ */
+ struct efx_short_copy_buffer copy_buf;
+
+ copy_buf.used = 0;
+
+ efx_skb_copy_bits_to_pio(tx_queue->efx, skb,
+ &piobuf, ©_buf);
+ efx_flush_copy_buffer(tx_queue->efx, piobuf, ©_buf);
+ } else {
+ /* Pad the write to the size of a cache line.
+ * We can do this because we know the skb_shared_info sruct is
+ * after the source, and the destination buffer is big enough.
+ */
+ BUILD_BUG_ON(L1_CACHE_BYTES >
+ SKB_DATA_ALIGN(sizeof(struct skb_shared_info)));
+ memcpy_toio(tx_queue->piobuf, skb->data,
+ ALIGN(skb->len, L1_CACHE_BYTES));
+ }
+
+ EFX_POPULATE_QWORD_5(buffer->option,
+ ESF_DZ_TX_DESC_IS_OPT, 1,
+ ESF_DZ_TX_OPTION_TYPE, ESE_DZ_TX_OPTION_DESC_PIO,
+ ESF_DZ_TX_PIO_CONT, 0,
+ ESF_DZ_TX_PIO_BYTE_CNT, skb->len,
+ ESF_DZ_TX_PIO_BUF_ADDR,
+ tx_queue->piobuf_offset);
+ ++tx_queue->pio_packets;
+ ++tx_queue->insert_count;
+ return buffer;
+}
+#endif /* EFX_USE_PIO */
+
/*
* Add a socket buffer to a TX queue
*
@@ -227,6 +366,17 @@ netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb)
return NETDEV_TX_OK;
}
+ /* Consider using PIO for short packets */
+#ifdef EFX_USE_PIO
+ if (skb->len <= efx_piobuf_size && tx_queue->piobuf &&
+ efx_nic_tx_is_empty(tx_queue) &&
+ efx_nic_tx_is_empty(efx_tx_queue_partner(tx_queue))) {
+ buffer = efx_enqueue_skb_pio(tx_queue, skb);
+ dma_flags = EFX_TX_BUF_OPTION;
+ goto finish_packet;
+ }
+#endif
+
/* Map for DMA. Use dma_map_single rather than dma_map_page
* since this is more efficient on machines with sparse
* memory.
@@ -279,6 +429,7 @@ netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb)
}
/* Transfer ownership of the skb to the final buffer */
+finish_packet:
buffer->skb = skb;
buffer->flags = EFX_TX_BUF_SKB | dma_flags;
--
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply related
* [PATCH net-next 10/11] sfc: Support ARFS for IPv6 flows
From: Ben Hutchings @ 2013-09-21 18:36 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
In-Reply-To: <1379788283.1681.34.camel@bwh-desktop.uk.level5networks.com>
Extend efx_filter_rfs() to map TCP/IPv6 and UDP/IPv6 flows into
efx_filter_spec. These are only supported on EF10; on Falcon and
Siena they will be rejected by efx_farch_filter_from_gen_spec().
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
drivers/net/ethernet/sfc/rx.c | 89 +++++++++++++++++++++++++++++--------------
1 file changed, 61 insertions(+), 28 deletions(-)
diff --git a/drivers/net/ethernet/sfc/rx.c b/drivers/net/ethernet/sfc/rx.c
index 4a59672..20c46f3 100644
--- a/drivers/net/ethernet/sfc/rx.c
+++ b/drivers/net/ethernet/sfc/rx.c
@@ -818,44 +818,70 @@ int efx_filter_rfs(struct net_device *net_dev, const struct sk_buff *skb,
struct efx_nic *efx = netdev_priv(net_dev);
struct efx_channel *channel;
struct efx_filter_spec spec;
- const struct iphdr *ip;
const __be16 *ports;
+ __be16 ether_type;
int nhoff;
int rc;
- nhoff = skb_network_offset(skb);
+ /* The core RPS/RFS code has already parsed and validated
+ * VLAN, IP and transport headers. We assume they are in the
+ * header area.
+ */
if (skb->protocol == htons(ETH_P_8021Q)) {
- EFX_BUG_ON_PARANOID(skb_headlen(skb) <
- nhoff + sizeof(struct vlan_hdr));
- if (((const struct vlan_hdr *)skb->data + nhoff)->
- h_vlan_encapsulated_proto != htons(ETH_P_IP))
- return -EPROTONOSUPPORT;
+ const struct vlan_hdr *vh =
+ (const struct vlan_hdr *)skb->data;
- /* This is IP over 802.1q VLAN. We can't filter on the
- * IP 5-tuple and the vlan together, so just strip the
- * vlan header and filter on the IP part.
+ /* We can't filter on the IP 5-tuple and the vlan
+ * together, so just strip the vlan header and filter
+ * on the IP part.
*/
- nhoff += sizeof(struct vlan_hdr);
- } else if (skb->protocol != htons(ETH_P_IP)) {
- return -EPROTONOSUPPORT;
+ EFX_BUG_ON_PARANOID(skb_headlen(skb) < sizeof(*vh));
+ ether_type = vh->h_vlan_encapsulated_proto;
+ nhoff = sizeof(struct vlan_hdr);
+ } else {
+ ether_type = skb->protocol;
+ nhoff = 0;
}
- /* RFS must validate the IP header length before calling us */
- EFX_BUG_ON_PARANOID(skb_headlen(skb) < nhoff + sizeof(*ip));
- ip = (const struct iphdr *)(skb->data + nhoff);
- if (ip_is_fragment(ip))
+ if (ether_type != htons(ETH_P_IP) && ether_type != htons(ETH_P_IPV6))
return -EPROTONOSUPPORT;
- EFX_BUG_ON_PARANOID(skb_headlen(skb) < nhoff + 4 * ip->ihl + 4);
- ports = (const __be16 *)(skb->data + nhoff + 4 * ip->ihl);
efx_filter_init_rx(&spec, EFX_FILTER_PRI_HINT,
efx->rx_scatter ? EFX_FILTER_FLAG_RX_SCATTER : 0,
rxq_index);
- rc = efx_filter_set_ipv4_full(&spec, ip->protocol,
- ip->daddr, ports[1], ip->saddr, ports[0]);
- if (rc)
- return rc;
+ spec.match_flags =
+ EFX_FILTER_MATCH_ETHER_TYPE | EFX_FILTER_MATCH_IP_PROTO |
+ EFX_FILTER_MATCH_LOC_HOST | EFX_FILTER_MATCH_LOC_PORT |
+ EFX_FILTER_MATCH_REM_HOST | EFX_FILTER_MATCH_REM_PORT;
+ spec.ether_type = ether_type;
+
+ if (ether_type == htons(ETH_P_IP)) {
+ const struct iphdr *ip =
+ (const struct iphdr *)(skb->data + nhoff);
+
+ EFX_BUG_ON_PARANOID(skb_headlen(skb) < nhoff + sizeof(*ip));
+ if (ip_is_fragment(ip))
+ return -EPROTONOSUPPORT;
+ spec.ip_proto = ip->protocol;
+ spec.rem_host[0] = ip->saddr;
+ spec.loc_host[0] = ip->daddr;
+ EFX_BUG_ON_PARANOID(skb_headlen(skb) < nhoff + 4 * ip->ihl + 4);
+ ports = (const __be16 *)(skb->data + nhoff + 4 * ip->ihl);
+ } else {
+ const struct ipv6hdr *ip6 =
+ (const struct ipv6hdr *)(skb->data + nhoff);
+
+ EFX_BUG_ON_PARANOID(skb_headlen(skb) <
+ nhoff + sizeof(*ip6) + 4);
+ spec.ip_proto = ip6->nexthdr;
+ memcpy(spec.rem_host, &ip6->saddr, sizeof(ip6->saddr));
+ memcpy(spec.loc_host, &ip6->daddr, sizeof(ip6->daddr));
+ ports = (const __be16 *)(ip6 + 1);
+ }
+
+ spec.rem_port = ports[0];
+ spec.loc_port = ports[1];
rc = efx->type->filter_rfs_insert(efx, &spec);
if (rc < 0)
@@ -866,11 +892,18 @@ int efx_filter_rfs(struct net_device *net_dev, const struct sk_buff *skb,
channel = efx_get_channel(efx, skb_get_rx_queue(skb));
++channel->rfs_filters_added;
- netif_info(efx, rx_status, efx->net_dev,
- "steering %s %pI4:%u:%pI4:%u to queue %u [flow %u filter %d]\n",
- (ip->protocol == IPPROTO_TCP) ? "TCP" : "UDP",
- &ip->saddr, ntohs(ports[0]), &ip->daddr, ntohs(ports[1]),
- rxq_index, flow_id, rc);
+ if (ether_type == htons(ETH_P_IP))
+ netif_info(efx, rx_status, efx->net_dev,
+ "steering %s %pI4:%u:%pI4:%u to queue %u [flow %u filter %d]\n",
+ (spec.ip_proto == IPPROTO_TCP) ? "TCP" : "UDP",
+ spec.rem_host, ntohs(ports[0]), spec.loc_host,
+ ntohs(ports[1]), rxq_index, flow_id, rc);
+ else
+ netif_info(efx, rx_status, efx->net_dev,
+ "steering %s [%pI6]:%u:[%pI6]:%u to queue %u [flow %u filter %d]\n",
+ (spec.ip_proto == IPPROTO_TCP) ? "TCP" : "UDP",
+ spec.rem_host, ntohs(ports[0]), spec.loc_host,
+ ntohs(ports[1]), rxq_index, flow_id, rc);
return rc;
}
--
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply related
* [PATCH net-next 11/11] sfc: Add static tracepoints to datapath
From: Ben Hutchings @ 2013-09-21 18:36 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
In-Reply-To: <1379788283.1681.34.camel@bwh-desktop.uk.level5networks.com>
These tracepoints support the driver-specific datapath feature tests
we're running internally, though they might be useful for other
purposes. The skb fields are chosen to cover driver features
implemented now or likely to be added soon.
(Includes a bug fix from Edward Cree.)
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
MAINTAINERS | 1 +
drivers/net/ethernet/sfc/Kconfig | 14 ++++
drivers/net/ethernet/sfc/efx.c | 6 ++
drivers/net/ethernet/sfc/ptp.c | 3 +
drivers/net/ethernet/sfc/rx.c | 3 +
drivers/net/ethernet/sfc/tx.c | 3 +
include/trace/events/sfc.h | 160 +++++++++++++++++++++++++++++++++++++++
7 files changed, 190 insertions(+)
create mode 100644 include/trace/events/sfc.h
diff --git a/MAINTAINERS b/MAINTAINERS
index b6b29c3..663c6e1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7424,6 +7424,7 @@ M: Ben Hutchings <bhutchings@solarflare.com>
L: netdev@vger.kernel.org
S: Supported
F: drivers/net/ethernet/sfc/
+F: include/trace/events/sfc.h
SGI GRU DRIVER
M: Dimitri Sivanich <sivanich@sgi.com>
diff --git a/drivers/net/ethernet/sfc/Kconfig b/drivers/net/ethernet/sfc/Kconfig
index 8b71525..15cab77 100644
--- a/drivers/net/ethernet/sfc/Kconfig
+++ b/drivers/net/ethernet/sfc/Kconfig
@@ -36,3 +36,17 @@ config SFC_SRIOV
This enables support for the SFC9000 I/O Virtualization
features, allowing accelerated network performance in
virtualized environments.
+config SFC_TRACING
+ bool "Solarflare datapath tracing"
+ depends on SFC
+ select GENERIC_TRACER
+ default n
+ ---help---
+ Enable tracing of packet RX and TX. If you say yes, sfc will
+ register with the tracing framework and generate an event
+ for each skb transferred, which can be dumped using ftrace.
+ You may need to increase the ftrace ringbuffer size. See the
+ ftrace documentation for more information.
+
+ When tracing is not enabled, this option still has some
+ overhead.
diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c
index 07c9bc4..97c2fda 100644
--- a/drivers/net/ethernet/sfc/efx.c
+++ b/drivers/net/ethernet/sfc/efx.c
@@ -30,6 +30,12 @@
#include "mcdi.h"
#include "workarounds.h"
+/* sparse doesn't like the tracepoint definitions */
+#ifndef __CHECKER__
+#define CREATE_TRACE_POINTS
+#include <trace/events/sfc.h>
+#endif
+
/**************************************************************************
*
* Type name strings
diff --git a/drivers/net/ethernet/sfc/ptp.c b/drivers/net/ethernet/sfc/ptp.c
index 03acf57..209c428 100644
--- a/drivers/net/ethernet/sfc/ptp.c
+++ b/drivers/net/ethernet/sfc/ptp.c
@@ -48,6 +48,7 @@
#include "io.h"
#include "farch_regs.h"
#include "nic.h"
+#include <trace/events/sfc.h>
/* Maximum number of events expected to make up a PTP event */
#define MAX_EVENT_FRAGS 3
@@ -343,6 +344,7 @@ static void efx_ptp_deliver_rx_queue(struct sk_buff_head *q)
while ((skb = skb_dequeue(q))) {
local_bh_disable();
+ trace_sfc_receive(skb, false);
netif_receive_skb(skb);
local_bh_enable();
}
@@ -722,6 +724,7 @@ static bool efx_ptp_process_events(struct efx_nic *efx, struct sk_buff_head *q)
static inline void efx_ptp_process_rx(struct efx_nic *efx, struct sk_buff *skb)
{
local_bh_disable();
+ trace_sfc_receive(skb, false);
netif_receive_skb(skb);
local_bh_enable();
}
diff --git a/drivers/net/ethernet/sfc/rx.c b/drivers/net/ethernet/sfc/rx.c
index 20c46f3..079b08f 100644
--- a/drivers/net/ethernet/sfc/rx.c
+++ b/drivers/net/ethernet/sfc/rx.c
@@ -25,6 +25,7 @@
#include "nic.h"
#include "selftest.h"
#include "workarounds.h"
+#include <trace/events/sfc.h>
/* Preferred number of descriptors to fill at once */
#define EFX_RX_PREFERRED_BATCH 8U
@@ -459,6 +460,7 @@ efx_rx_packet_gro(struct efx_channel *channel, struct efx_rx_buffer *rx_buf,
skb_record_rx_queue(skb, channel->rx_queue.core_index);
+ trace_sfc_receive(skb, true);
gro_result = napi_gro_frags(napi);
if (gro_result != GRO_DROP)
channel->irq_mod_score += 2;
@@ -623,6 +625,7 @@ static void efx_rx_deliver(struct efx_channel *channel, u8 *eh,
return;
/* Pass the packet up */
+ trace_sfc_receive(skb, false);
netif_receive_skb(skb);
}
diff --git a/drivers/net/ethernet/sfc/tx.c b/drivers/net/ethernet/sfc/tx.c
index 282692c..bc35f44 100644
--- a/drivers/net/ethernet/sfc/tx.c
+++ b/drivers/net/ethernet/sfc/tx.c
@@ -24,6 +24,7 @@
#include "nic.h"
#include "workarounds.h"
#include "ef10_regs.h"
+#include <trace/events/sfc.h>
#ifdef EFX_USE_PIO
@@ -525,6 +526,8 @@ netdev_tx_t efx_hard_start_xmit(struct sk_buff *skb,
EFX_WARN_ON_PARANOID(!netif_device_present(net_dev));
+ trace_sfc_transmit(skb, net_dev);
+
/* PTP "event" packet */
if (unlikely(efx_xmit_with_hwtstamp(skb)) &&
unlikely(efx_ptp_is_ptp_tx(efx, skb))) {
diff --git a/include/trace/events/sfc.h b/include/trace/events/sfc.h
new file mode 100644
index 0000000..a158849
--- /dev/null
+++ b/include/trace/events/sfc.h
@@ -0,0 +1,160 @@
+/****************************************************************************
+ * Driver for Solarflare network controllers and boards
+ * Copyright 2013 Solarflare Communications Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation, incorporated herein by reference.
+ */
+
+/* sparse doesn't like the tracepoint definitions. It will complain
+ * about the tracepoint functions being undefined now, but at least it
+ * won't give up after trying to parse this file.
+ */
+#ifndef __CHECKER__
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM sfc
+
+#if !defined(TRACE_EVENTS_SFC_H) || defined(TRACE_HEADER_MULTI_READ)
+#define TRACE_EVENTS_SFC_H
+
+#ifndef CONFIG_SFC_TRACING
+#undef TP_PROTO
+#define TP_PROTO(proto...) proto
+#undef TRACE_EVENT
+#define TRACE_EVENT(name, proto, ...) \
+ static inline void trace_ ## name(proto) {}
+#else
+#include <linux/tracepoint.h>
+#endif
+
+TRACE_EVENT(sfc_receive,
+
+ TP_PROTO(const struct sk_buff *skb, bool gro),
+
+ TP_ARGS(skb, gro),
+
+ TP_STRUCT__entry(
+ __string( dev_name, skb->dev->name )
+ __field( unsigned int, napi_id )
+ __field( u16, queue_mapping )
+ __field( const void *, skbaddr )
+ __field( bool, gro )
+ __field( bool, vlan_tagged )
+ __field( u16, vlan_proto )
+ __field( u16, vlan_tci )
+ __field( u16, protocol )
+ __field( u8, ip_summed )
+ __field( u32, rxhash )
+ __field( bool, l4_rxhash )
+ __field( unsigned int, len )
+ __field( unsigned int, data_len )
+ __field( unsigned int, truesize )
+ __field( bool, mac_header_valid)
+ __field( int, mac_header )
+ __field( unsigned char, nr_frags )
+ __field( u16, gso_size )
+ __field( u16, gso_type )
+ ),
+
+ TP_fast_assign(
+ __assign_str(dev_name, skb->dev->name);
+#ifdef CONFIG_NET_LL_RX_POLL
+ __entry->napi_id = skb->napi_id;
+#else
+ __entry->napi_id = 0;
+#endif
+ __entry->queue_mapping = skb->queue_mapping;
+ __entry->skbaddr = skb;
+ __entry->gro = gro;
+ __entry->vlan_tagged = vlan_tx_tag_present(skb);
+ __entry->vlan_proto = ntohs(skb->vlan_proto);
+ __entry->vlan_tci = vlan_tx_tag_get(skb);
+ __entry->protocol = ntohs(skb->protocol);
+ __entry->ip_summed = skb->ip_summed;
+ __entry->rxhash = skb->rxhash;
+ __entry->l4_rxhash = skb->l4_rxhash;
+ __entry->len = skb->len;
+ __entry->data_len = skb->data_len;
+ __entry->truesize = skb->truesize;
+ __entry->mac_header_valid = skb_mac_header_was_set(skb);
+ __entry->mac_header = skb_mac_header(skb) - skb->data;
+ __entry->nr_frags = skb_shinfo(skb)->nr_frags;
+ __entry->gso_size = skb_shinfo(skb)->gso_size;
+ __entry->gso_type = skb_shinfo(skb)->gso_type;
+ ),
+
+ TP_printk("dev_name=%s napi_id=%#x queue_mapping=%u skbaddr=%p gro=%d vlan_tagged=%d vlan_proto=0x%04x vlan_tci=0x%04x protocol=0x%04x ip_summed=%d rxhash=0x%08x l4_rxhash=%d len=%u data_len=%u truesize=%u mac_header_valid=%d mac_header=%d nr_frags=%d gso_size=%d gso_type=%#x",
+ __get_str(dev_name), __entry->napi_id, __entry->queue_mapping,
+ __entry->skbaddr, __entry->gro, __entry->vlan_tagged,
+ __entry->vlan_proto, __entry->vlan_tci, __entry->protocol,
+ __entry->ip_summed, __entry->rxhash, __entry->l4_rxhash,
+ __entry->len, __entry->data_len, __entry->truesize,
+ __entry->mac_header_valid, __entry->mac_header,
+ __entry->nr_frags, __entry->gso_size, __entry->gso_type)
+);
+
+TRACE_EVENT(sfc_transmit,
+
+ TP_PROTO(const struct sk_buff *skb, const struct net_device *net_dev),
+
+ TP_ARGS(skb, net_dev),
+
+ TP_STRUCT__entry(
+ __string( dev_name, net_dev->name )
+ __field( u16, queue_mapping )
+ __field( const void *, skbaddr )
+ __field( bool, vlan_tagged )
+ __field( u16, vlan_proto )
+ __field( u16, vlan_tci )
+ __field( u16, protocol )
+ __field( u8, ip_summed )
+ __field( unsigned int, len )
+ __field( unsigned int, data_len )
+ __field( int, network_offset )
+ __field( bool, transport_offset_valid)
+ __field( int, transport_offset)
+ __field( u8, tx_flags )
+ __field( u16, gso_size )
+ __field( u16, gso_segs )
+ __field( u16, gso_type )
+ ),
+
+ TP_fast_assign(
+ __assign_str(dev_name, net_dev->name);
+ __entry->queue_mapping = skb->queue_mapping;
+ __entry->skbaddr = skb;
+ __entry->vlan_tagged = vlan_tx_tag_present(skb);
+ __entry->vlan_proto = ntohs(skb->vlan_proto);
+ __entry->vlan_tci = vlan_tx_tag_get(skb);
+ __entry->protocol = ntohs(skb->protocol);
+ __entry->ip_summed = skb->ip_summed;
+ __entry->len = skb->len;
+ __entry->data_len = skb->data_len;
+ __entry->network_offset = skb_network_offset(skb);
+ __entry->transport_offset_valid =
+ skb_transport_header_was_set(skb);
+ __entry->transport_offset = skb_transport_offset(skb);
+ __entry->tx_flags = skb_shinfo(skb)->tx_flags;
+ __entry->gso_size = skb_shinfo(skb)->gso_size;
+ __entry->gso_segs = skb_shinfo(skb)->gso_segs;
+ __entry->gso_type = skb_shinfo(skb)->gso_type;
+ ),
+
+ TP_printk("dev_name=%s queue_mapping=%u skbaddr=%p vlan_tagged=%d vlan_proto=0x%04x vlan_tci=0x%04x protocol=0x%04x ip_summed=%d len=%u data_len=%u network_offset=%d transport_offset_valid=%d transport_offset=%d tx_flags=%d gso_size=%d gso_segs=%d gso_type=%#x",
+ __get_str(dev_name), __entry->queue_mapping, __entry->skbaddr,
+ __entry->vlan_tagged, __entry->vlan_proto, __entry->vlan_tci,
+ __entry->protocol, __entry->ip_summed, __entry->len, __entry->data_len,
+ __entry->network_offset, __entry->transport_offset_valid,
+ __entry->transport_offset, __entry->tx_flags,
+ __entry->gso_size, __entry->gso_segs, __entry->gso_type)
+);
+
+#endif /* TRACE_EVENTS_SFC_H */
+
+#ifdef CONFIG_SFC_TRACING
+#include <trace/define_trace.h>
+#endif
+
+#endif /* __CHECKER__ */
--
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply related
* [net-next] hp100: replace hardcoded name in /proc/interrupts with interface name
From: Mihir Singh @ 2013-09-21 18:48 UTC (permalink / raw)
To: netdev; +Cc: Mihir Singh
The /proc/interrupts file displays hp100, which is not the accepted style. Printing eth%d is more helpful.
Signed-off-by: Mihir Singh <me@mihirsingh.com>
---
drivers/net/ethernet/hp/hp100.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/hp/hp100.c b/drivers/net/ethernet/hp/hp100.c
index 91227d0..3786009 100644
--- a/drivers/net/ethernet/hp/hp100.c
+++ b/drivers/net/ethernet/hp/hp100.c
@@ -1098,7 +1098,7 @@ static int hp100_open(struct net_device *dev)
if (request_irq(dev->irq, hp100_interrupt,
lp->bus == HP100_BUS_PCI || lp->bus ==
HP100_BUS_EISA ? IRQF_SHARED : 0,
- "hp100", dev)) {
+ dev->name, dev)) {
printk("hp100: %s: unable to get IRQ %d\n", dev->name, dev->irq);
return -EAGAIN;
}
--
1.8.1.2
^ permalink raw reply related
* [net-next] Fix hardcoded interrupt name lp->name to use system device value
From: Nate Levesque @ 2013-09-21 18:49 UTC (permalink / raw)
To: netdev; +Cc: Nate Levesque
The lance interrupt handler was using the hard-coded name which would make it difficult to tell where the interrupt came from. Changed to use the device name that made the interrupt.
Signed-off-by: Nate Levesque <thenaterhood@gmail.com>
---
drivers/net/ethernet/amd/lance.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/amd/lance.c b/drivers/net/ethernet/amd/lance.c
index 5c72843..256f590 100644
--- a/drivers/net/ethernet/amd/lance.c
+++ b/drivers/net/ethernet/amd/lance.c
@@ -754,7 +754,7 @@ lance_open(struct net_device *dev)
int i;
if (dev->irq == 0 ||
- request_irq(dev->irq, lance_interrupt, 0, lp->name, dev)) {
+ request_irq(dev->irq, lance_interrupt, 0, dev->name, dev)) {
return -EAGAIN;
}
--
1.8.1.2
^ permalink raw reply related
* [net-next] Fix hardcoded ni65 interrupt name to use system device value
From: Mark Repka @ 2013-09-21 19:32 UTC (permalink / raw)
To: netdev; +Cc: Mark Repka
The ni65 interrupt handler was using the hard-coded name which would make it difficult to tell where the interrupt came from. Changed to use the device name that made the interrupt.
Signed-off-by: Mark Repka <repkam09@gmail.com>
---
drivers/net/ethernet/amd/ni65.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/amd/ni65.c b/drivers/net/ethernet/amd/ni65.c
index 1cf33ad..00cb6db 100644
--- a/drivers/net/ethernet/amd/ni65.c
+++ b/drivers/net/ethernet/amd/ni65.c
@@ -295,7 +295,7 @@ static int ni65_open(struct net_device *dev)
{
struct priv *p = dev->ml_priv;
int irqval = request_irq(dev->irq, ni65_interrupt,0,
- cards[p->cardno].cardname,dev);
+ dev->name,dev);
if (irqval) {
printk(KERN_ERR "%s: unable to get IRQ %d (irqval=%d).\n",
dev->name,dev->irq, irqval);
--
1.8.1.4
^ permalink raw reply related
* Re: [net-next] Fix hardcoded ni65 interrupt name to use system device value
From: Sergei Shtylyov @ 2013-09-21 19:48 UTC (permalink / raw)
To: Mark Repka; +Cc: netdev
In-Reply-To: <1379791939-23887-1-git-send-email-repkam09@gmail.com>
Hello.
On 09/21/2013 11:32 PM, Mark Repka wrote:
> The ni65 interrupt handler was using the hard-coded name which would make it difficult to tell where the interrupt came from. Changed to use the device name that made the interrupt.
Please wrap your changelog lines at 80 columns (preferably even less).
> Signed-off-by: Mark Repka <repkam09@gmail.com>
> ---
> drivers/net/ethernet/amd/ni65.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
> diff --git a/drivers/net/ethernet/amd/ni65.c b/drivers/net/ethernet/amd/ni65.c
> index 1cf33ad..00cb6db 100644
> --- a/drivers/net/ethernet/amd/ni65.c
> +++ b/drivers/net/ethernet/amd/ni65.c
> @@ -295,7 +295,7 @@ static int ni65_open(struct net_device *dev)
> {
> struct priv *p = dev->ml_priv;
> int irqval = request_irq(dev->irq, ni65_interrupt,0,
> - cards[p->cardno].cardname,dev);
> + dev->name,dev);
Don't indent with all spaces, use tabs at the start of line. And start the
line under 'dev->irq' please.
WBR, Sergei
^ permalink raw reply
* Re: [PATCH 13/51] DMA-API: net: sfc/efx.c: replace dma_set_mask()+dma_set_coherent_mask() with new helper
From: Russell King - ARM Linux @ 2013-09-21 19:50 UTC (permalink / raw)
To: Ben Hutchings; +Cc: netdev, Solarflare linux maintainers
In-Reply-To: <1379685328.1681.0.camel@bwh-desktop.uk.level5networks.com>
On Fri, Sep 20, 2013 at 02:55:28PM +0100, Ben Hutchings wrote:
> Acked-by: Ben Hutchings <bhutchings@solarflare.com>
Thanks, added.
^ permalink raw reply
* Re: [PATCH 18/51] DMA-API: staging: et131x: replace dma_set_mask()+dma_set_coherent_mask() with new helper
From: Russell King - ARM Linux @ 2013-09-21 19:55 UTC (permalink / raw)
To: Ben Hutchings; +Cc: devel, netdev
In-Reply-To: <1379691728.1681.15.camel@bwh-desktop.uk.level5networks.com>
On Fri, Sep 20, 2013 at 04:42:08PM +0100, Ben Hutchings wrote:
> On Thu, 2013-09-19 at 22:43 +0100, Russell King wrote:
> > + if (dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)) ||
> > + dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32))) {
>
> Surely we want && here.
Good catch, exactly right. Thanks for the review, here's the replacement
patch:
8<====
From: Russell King <rmk+kernel@arm.linux.org.uk>
Subject: [PATCH] DMA-API: staging: et131x: replace
dma_set_mask()+dma_set_coherent_mask() with new helper
Replace the following sequence:
dma_set_mask(dev, mask);
dma_set_coherent_mask(dev, mask);
with a call to the new helper dma_set_mask_and_coherent().
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
drivers/staging/et131x/et131x.c | 17 ++---------------
1 files changed, 2 insertions(+), 15 deletions(-)
diff --git a/drivers/staging/et131x/et131x.c b/drivers/staging/et131x/et131x.c
index f73e58f..61da7ee 100644
--- a/drivers/staging/et131x/et131x.c
+++ b/drivers/staging/et131x/et131x.c
@@ -4797,21 +4797,8 @@ static int et131x_pci_setup(struct pci_dev *pdev,
pci_set_master(pdev);
/* Check the DMA addressing support of this device */
- if (!dma_set_mask(&pdev->dev, DMA_BIT_MASK(64))) {
- rc = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64));
- if (rc < 0) {
- dev_err(&pdev->dev,
- "Unable to obtain 64 bit DMA for consistent allocations\n");
- goto err_release_res;
- }
- } else if (!dma_set_mask(&pdev->dev, DMA_BIT_MASK(32))) {
- rc = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
- if (rc < 0) {
- dev_err(&pdev->dev,
- "Unable to obtain 32 bit DMA for consistent allocations\n");
- goto err_release_res;
- }
- } else {
+ if (dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)) &&
+ dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32))) {
dev_err(&pdev->dev, "No usable DMA addressing method\n");
rc = -EIO;
goto err_release_res;
--
1.7.4.4
^ permalink raw reply related
* Re: [PATCH 24/51] DMA-API: dma: pl330: add dma_set_mask_and_coherent() call
From: Russell King - ARM Linux @ 2013-09-21 20:00 UTC (permalink / raw)
To: Heiko Stübner
Cc: alsa-devel, linux-doc, linux-mmc, linux-fbdev, linux-nvme,
linux-ide, devel, linux-samsung-soc, linux-scsi, e1000-devel,
b43-dev, linux-media, devicetree, dri-devel, linux-tegra,
Dan Williams, linux-omap, linux-arm-kernel,
Solarflare linux maintainers, netdev, linux-usb, linux-wireless,
Vinod Koul, linux-crypto, uclinux-dist-devel, linuxppc-dev
In-Reply-To: <201309201926.29084.heiko@sntech.de>
On Fri, Sep 20, 2013 at 07:26:27PM +0200, Heiko Stübner wrote:
> Am Donnerstag, 19. September 2013, 23:49:01 schrieb Russell King:
> > The DMA API requires drivers to call the appropriate dma_set_mask()
> > functions before doing any DMA mapping. Add this required call to
> > the AMBA PL08x driver.
> ^--- copy and paste error - should of course be PL330
Fixed, thanks.
^ permalink raw reply
* [--signoff] Changes made for Lance.c
From: Ubuntu @ 2013-09-21 20:17 UTC (permalink / raw)
To: netdev; +Cc: dinesh
From: dinesh <dineshraju2007@gmail.com>
---
drivers/net/ethernet/amd/lance.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/amd/lance.c b/drivers/net/ethernet/amd/lance.c
index 5c72843..256f590 100644
--- a/drivers/net/ethernet/amd/lance.c
+++ b/drivers/net/ethernet/amd/lance.c
@@ -754,7 +754,7 @@ lance_open(struct net_device *dev)
int i;
if (dev->irq == 0 ||
- request_irq(dev->irq, lance_interrupt, 0, lp->name, dev)) {
+ request_irq(dev->irq, lance_interrupt, 0, dev->name, dev)) {
return -EAGAIN;
}
--
1.8.1.2
^ permalink raw reply related
* Re: [PATCH] skge: fix invalid value passed to pci_unmap_sigle
From: Sergei Shtylyov @ 2013-09-21 22:12 UTC (permalink / raw)
To: Mikulas Patocka
Cc: David Miller, netdev, Francois Romieu, Igor Gnatenko, stephen
In-Reply-To: <alpine.LRH.2.02.1309201352010.1763@file01.intranet.prod.int.rdu2.redhat.com>
Hello.
On 09/20/2013 09:53 PM, Mikulas Patocka wrote:
> In my patch c194992cbe71c20bb3623a566af8d11b0bfaa721 I didn't fix the skge
Please also specify that commit's summary in parens.
> bug correctly. The value of the new mapping (not old) was passed to
> pci_unmap_single.
> If we enable CONFIG_DMA_API_DEBUG, it results in this warning:
> WARNING: CPU: 0 PID: 0 at lib/dma-debug.c:986 check_sync+0x4c4/0x580()
> skge 0000:02:07.0: DMA-API: device driver tries to sync DMA memory it has
> not allocated [device address=0x000000023a0096c0] [size=1536 bytes]
> This patch makes the skge driver pass the correct value to
> pci_unmap_single and fixes the warning. It copies the old descriptor to
> on-stack variable "ee" and unmaps it if mapping of the new descriptor
> succeeded.
> This patch should be backported to 3.11-stable.
> Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
> Reported-by: Francois Romieu <romieu@fr.zoreil.com>
> Tested-by: Mikulas Patocka <mpatocka@redhat.com>
WBR, Sergei
^ permalink raw reply
* [PATCH 04/19] isdn: Change variable type to bool
From: Peter Senna Tschudin @ 2013-09-21 22:27 UTC (permalink / raw)
To: mac; +Cc: isdn4linux, netdev, linux-kernel, kernel-janitors,
Peter Senna Tschudin
In-Reply-To: <1379802471-30252-1-git-send-email-peter.senna@gmail.com>
The variable noCh is only assigned the values true and false. Change
its type to bool.
The simplified semantic patch that find this problem is as
follows (http://coccinelle.lip6.fr/):
@exists@
type T;
identifier b;
@@
- T
+ bool
b = ...;
... when any
b = \(true\|false\)
Signed-off-by: Peter Senna Tschudin <peter.senna@gmail.com>
---
drivers/isdn/hardware/eicon/message.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/isdn/hardware/eicon/message.c b/drivers/isdn/hardware/eicon/message.c
index a82e542..05d889a 100644
--- a/drivers/isdn/hardware/eicon/message.c
+++ b/drivers/isdn/hardware/eicon/message.c
@@ -1207,7 +1207,7 @@ static byte connect_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
byte m;
static byte esc_chi[35] = {0x02, 0x18, 0x01};
static byte lli[2] = {0x01, 0x00};
- byte noCh = 0;
+ bool noCh = false;
word dir = 0;
byte *p_chi = "";
--
1.8.3.1
^ permalink raw reply related
* [PATCH 08/19] net: Change variable type to bool
From: Peter Senna Tschudin @ 2013-09-21 22:27 UTC (permalink / raw)
To: jcliburn
Cc: chris.snook, jkosina, rdunlap, standby24x7, peter.senna, netdev,
linux-kernel, kernel-janitors
In-Reply-To: <1379802471-30252-1-git-send-email-peter.senna@gmail.com>
The variable ret is only assigned the values true and false.
The function atl1c_read_eeprom already returns bool. Change
ret type to bool.
The simplified semantic patch that find this problem is as
follows (http://coccinelle.lip6.fr/):
@exists@
type T;
identifier b;
@@
- T
+ bool
b = ...;
... when any
b = \(true\|false\)
Signed-off-by: Peter Senna Tschudin <peter.senna@gmail.com>
---
drivers/net/ethernet/atheros/atl1c/atl1c_hw.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_hw.c b/drivers/net/ethernet/atheros/atl1c/atl1c_hw.c
index 3ef7092..1cda49a 100644
--- a/drivers/net/ethernet/atheros/atl1c/atl1c_hw.c
+++ b/drivers/net/ethernet/atheros/atl1c/atl1c_hw.c
@@ -153,7 +153,7 @@ static int atl1c_get_permanent_address(struct atl1c_hw *hw)
bool atl1c_read_eeprom(struct atl1c_hw *hw, u32 offset, u32 *p_value)
{
int i;
- int ret = false;
+ bool ret = false;
u32 otp_ctrl_data;
u32 control;
u32 data;
--
1.8.3.1
^ permalink raw reply related
* [PATCH 09/19] net: Change variable type to bool
From: Peter Senna Tschudin @ 2013-09-21 22:27 UTC (permalink / raw)
To: eilong; +Cc: netdev, linux-kernel, kernel-janitors, Peter Senna Tschudin
In-Reply-To: <1379802471-30252-1-git-send-email-peter.senna@gmail.com>
The variable rc is only assigned the values true and false.
The function bnx2x_prev_is_path_marked already returns bool.
Change rc type to bool.
The simplified semantic patch that find this problem is as
follows (http://coccinelle.lip6.fr/):
@exists@
type T;
identifier b;
@@
- T
+ bool
b = ...;
... when any
b = \(true\|false\)
Signed-off-by: Peter Senna Tschudin <peter.senna@gmail.com>
---
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index fccfc1d..105cc80 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -9874,7 +9874,7 @@ static int bnx2x_prev_path_mark_eeh(struct bnx2x *bp)
static bool bnx2x_prev_is_path_marked(struct bnx2x *bp)
{
struct bnx2x_prev_path_list *tmp_list;
- int rc = false;
+ bool rc = false;
if (down_trylock(&bnx2x_prev_sem))
return false;
--
1.8.3.1
^ permalink raw reply related
* [PATCH 10/19] net: Change variable type to bool
From: Peter Senna Tschudin @ 2013-09-21 22:27 UTC (permalink / raw)
To: hykim; +Cc: netdev, linux-kernel, kernel-janitors, Peter Senna Tschudin
In-Reply-To: <1379802471-30252-1-git-send-email-peter.senna@gmail.com>
There is the rc variable on both myri10ge_ss_lock_napi and
myri10ge_ss_lock_poll functions. In both cases rc is only assigned the
values true and false. Both functions already return bool. Change rc
type to bool.
The simplified semantic patch that find this problem is as
follows (http://coccinelle.lip6.fr/):
@exists@
type T;
identifier b;
@@
- T
+ bool
b = ...;
... when any
b = \(true\|false\)
Signed-off-by: Peter Senna Tschudin <peter.senna@gmail.com>
---
drivers/net/ethernet/myricom/myri10ge/myri10ge.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
index 149355b..7792264 100644
--- a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
+++ b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
@@ -934,7 +934,7 @@ static inline void myri10ge_ss_init_lock(struct myri10ge_slice_state *ss)
static inline bool myri10ge_ss_lock_napi(struct myri10ge_slice_state *ss)
{
- int rc = true;
+ bool rc = true;
spin_lock(&ss->lock);
if ((ss->state & SLICE_LOCKED)) {
WARN_ON((ss->state & SLICE_STATE_NAPI));
@@ -957,7 +957,7 @@ static inline void myri10ge_ss_unlock_napi(struct myri10ge_slice_state *ss)
static inline bool myri10ge_ss_lock_poll(struct myri10ge_slice_state *ss)
{
- int rc = true;
+ bool rc = true;
spin_lock_bh(&ss->lock);
if ((ss->state & SLICE_LOCKED)) {
ss->state |= SLICE_STATE_POLL_YIELD;
--
1.8.3.1
^ permalink raw reply related
* [PATCH 11/19] wireless: Change variable type to bool
From: Peter Senna Tschudin @ 2013-09-21 22:27 UTC (permalink / raw)
To: bzhao
Cc: linville, linux-wireless, netdev, linux-kernel, kernel-janitors,
Peter Senna Tschudin
In-Reply-To: <1379802471-30252-1-git-send-email-peter.senna@gmail.com>
The variables cancel_scan_cmd, enable_data, hs_activate and valid are
only assigned the values true and false. Change its type to bool.
The simplified semantic patch that find this problem is as
follows (http://coccinelle.lip6.fr/):
@exists@
type T;
identifier b;
@@
- T
+ bool
b = ...;
... when any
b = \(true\|false\)
Signed-off-by: Peter Senna Tschudin <peter.senna@gmail.com>
---
drivers/net/wireless/mwifiex/cmdevt.c | 2 +-
drivers/net/wireless/mwifiex/join.c | 2 +-
drivers/net/wireless/mwifiex/sta_cmd.c | 2 +-
drivers/net/wireless/mwifiex/wmm.c | 2 +-
4 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c
index 2d76147..fb3fa18 100644
--- a/drivers/net/wireless/mwifiex/cmdevt.c
+++ b/drivers/net/wireless/mwifiex/cmdevt.c
@@ -1048,7 +1048,7 @@ mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter)
struct cmd_ctrl_node *cmd_node = NULL, *tmp_node = NULL;
unsigned long cmd_flags;
unsigned long scan_pending_q_flags;
- uint16_t cancel_scan_cmd = false;
+ bool cancel_scan_cmd = false;
if ((adapter->curr_cmd) &&
(adapter->curr_cmd->wait_q_enabled)) {
diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c
index 9d7c0e6..717fbe2 100644
--- a/drivers/net/wireless/mwifiex/join.c
+++ b/drivers/net/wireless/mwifiex/join.c
@@ -621,7 +621,7 @@ int mwifiex_ret_802_11_associate(struct mwifiex_private *priv,
int ret = 0;
struct ieee_types_assoc_rsp *assoc_rsp;
struct mwifiex_bssdescriptor *bss_desc;
- u8 enable_data = true;
+ bool enable_data = true;
u16 cap_info, status_code;
assoc_rsp = (struct ieee_types_assoc_rsp *) &resp->params;
diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c
index c0268b5..7d66018 100644
--- a/drivers/net/wireless/mwifiex/sta_cmd.c
+++ b/drivers/net/wireless/mwifiex/sta_cmd.c
@@ -327,7 +327,7 @@ mwifiex_cmd_802_11_hs_cfg(struct mwifiex_private *priv,
{
struct mwifiex_adapter *adapter = priv->adapter;
struct host_cmd_ds_802_11_hs_cfg_enh *hs_cfg = &cmd->params.opt_hs_cfg;
- u16 hs_activate = false;
+ bool hs_activate = false;
if (!hscfg_param)
/* New Activate command */
diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c
index 2e8f9cd..8f8fea0 100644
--- a/drivers/net/wireless/mwifiex/wmm.c
+++ b/drivers/net/wireless/mwifiex/wmm.c
@@ -708,7 +708,7 @@ int mwifiex_ret_wmm_get_status(struct mwifiex_private *priv,
{
u8 *curr = (u8 *) &resp->params.get_wmm_status;
uint16_t resp_len = le16_to_cpu(resp->size), tlv_len;
- int valid = true;
+ bool valid = true;
struct mwifiex_ie_types_data *tlv_hdr;
struct mwifiex_ie_types_wmm_queue_status *tlv_wmm_qstatus;
--
1.8.3.1
^ permalink raw reply related
* [PATCH 12/19] wireless: Change variable type to bool
From: Peter Senna Tschudin @ 2013-09-21 22:27 UTC (permalink / raw)
To: Larry.Finger
Cc: chaoming_li, linville, linux-wireless, netdev, linux-kernel,
kernel-janitors, Peter Senna Tschudin
In-Reply-To: <1379802471-30252-1-git-send-email-peter.senna@gmail.com>
The variable continual is only assigned the values true and false.
Change its type to bool.
The simplified semantic patch that find this problem is as
follows (http://coccinelle.lip6.fr/):
@exists@
type T;
identifier b;
@@
- T
+ bool
b = ...;
... when any
b = \(true\|false\)
Signed-off-by: Peter Senna Tschudin <peter.senna@gmail.com>
---
drivers/net/wireless/rtlwifi/efuse.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/rtlwifi/efuse.c b/drivers/net/wireless/rtlwifi/efuse.c
index 838a1ed..63d370d 100644
--- a/drivers/net/wireless/rtlwifi/efuse.c
+++ b/drivers/net/wireless/rtlwifi/efuse.c
@@ -1203,7 +1203,7 @@ static void efuse_power_switch(struct ieee80211_hw *hw, u8 write, u8 pwrstate)
static u16 efuse_get_current_size(struct ieee80211_hw *hw)
{
- int continual = true;
+ bool continual = true;
u16 efuse_addr = 0;
u8 hworden;
u8 efuse_data, word_cnts;
--
1.8.3.1
^ permalink raw reply related
* [PATCH 19/19] net: Change variable type to bool
From: Peter Senna Tschudin @ 2013-09-21 22:27 UTC (permalink / raw)
To: davem
Cc: kuznet, jmorris, kaber, netdev, linux-kernel, kernel-janitors,
Peter Senna Tschudin
In-Reply-To: <1379802471-30252-1-git-send-email-peter.senna@gmail.com>
The variable fully_acked is only assigned the values true and false.
Change its type to bool.
The simplified semantic patch that find this problem is as
follows (http://coccinelle.lip6.fr/):
@exists@
type T;
identifier b;
@@
- T
+ bool
b = ...;
... when any
b = \(true\|false\)
Signed-off-by: Peter Senna Tschudin <peter.senna@gmail.com>
---
net/ipv4/tcp_input.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 25a89ea..fa17dce 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -2970,7 +2970,7 @@ static int tcp_clean_rtx_queue(struct sock *sk, int prior_fackets,
const struct inet_connection_sock *icsk = inet_csk(sk);
struct sk_buff *skb;
u32 now = tcp_time_stamp;
- int fully_acked = true;
+ bool fully_acked = true;
int flag = 0;
u32 pkts_acked = 0;
u32 reord = tp->packets_out;
--
1.8.3.1
^ permalink raw reply related
* Re: [PATCH] declance: Remove `incompatible pointer type' warnings
From: Sergei Shtylyov @ 2013-09-21 22:41 UTC (permalink / raw)
To: Maciej W. Rozycki; +Cc: netdev
In-Reply-To: <alpine.LFD.2.03.1309200008060.5967@linux-mips.org>
Hello.
On 09/20/2013 03:49 AM, Maciej W. Rozycki wrote:
> Revert damage caused by 43d620c82985b19008d87a437b4cf83f356264f7:
Please also specify that commit's summary in parens. That's the only way
to uniquely identify a commit and makes life a bit easier when you browse the
commits.
> .../declance.c: In function 'cp_to_buf':
> .../declance.c:347: warning: assignment from incompatible pointer type
> .../declance.c:348: warning: assignment from incompatible pointer type
> .../declance.c: In function 'cp_from_buf':
> .../declance.c:406: warning: assignment from incompatible pointer type
> .../declance.c:407: warning: assignment from incompatible pointer type
> Also add a `const' qualifier where applicable and adjust formatting.
> Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
WBR, Sergei
^ permalink raw reply
* [PATCH ethtool] Fix iteration count in sff8472_calibration()
From: Ben Hutchings @ 2013-09-22 1:36 UTC (permalink / raw)
To: Ben Hutchings; +Cc: netdev, Aurelien Guillaume
[-- Attachment #1: Type: text/plain, Size: 962 bytes --]
We want to iterate over all elements of the various arrays of readings
(which all have the same dimensions - and maybe ought to be a single
array). Unfortunately the iteration count is sizeof(sd->bias_cur) and
bias_cur has 2-byte elements, so we iterate over twice as many
elements as are really there.
Compiler-detected, and compile-tested only.
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
sfpdiag.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sfpdiag.c b/sfpdiag.c
index f67e491..04fd880 100644
--- a/sfpdiag.c
+++ b/sfpdiag.c
@@ -224,7 +224,7 @@ static void sff8472_calibration(const __u8 *id, struct sff8472_diags *sd)
__u16 rx_reading;
/* Calibration should occur for all values (threshold and current) */
- for (i = 0; i < sizeof(sd->bias_cur); ++i) {
+ for (i = 0; i < ARRAY_SIZE(sd->bias_cur); ++i) {
/*
* Apply calibration formula 1 (Temp., Voltage, Bias, Tx Power)
*/
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 828 bytes --]
^ permalink raw reply related
* Re: [Xen-devel] TSQ accounting skb->truesize degrades throughput for large packets
From: Cong Wang @ 2013-09-22 2:36 UTC (permalink / raw)
To: Wei Liu; +Cc: xen-devel, Linux Kernel Network Developers, Eric Dumazet
In-Reply-To: <20130921150327.GA9078@zion.uk.xensource.com>
On Sat, Sep 21, 2013 at 11:03 PM, Wei Liu <wei.liu2@citrix.com> wrote:
> On Sat, Sep 21, 2013 at 03:00:26AM +0000, Cong Wang wrote:
>> Eric Dumazet <eric.dumazet <at> gmail.com> writes:
>>
>> >
>> > Yeah, my own test was more like the following
>> >
>> ...
>> >
>> > Note that it also seems to make Hystart happier.
>> >
>> > I will send patches when all tests are green.
>> >
>>
>> How is this going? I don't see any patch posted to netdev.
>>
>
> I'm afraid you forgot to CC any relevant people in thie email. :-)
>
I was replying via newsgroup, not mailing list. :)
Anyway, adding Eric and netdev now.
^ permalink raw reply
* Re: [Xen-devel] [PATCH net-next v2 1/2] xen-netback: add a vif-is-connected flag
From: annie li @ 2013-09-22 2:56 UTC (permalink / raw)
To: Paul Durrant; +Cc: netdev, xen-devel, Wei Liu, David Vrabel, Ian Campbell
In-Reply-To: <1379685460-25032-2-git-send-email-paul.durrant@citrix.com>
On 2013-9-20 21:57, Paul Durrant wrote:
> Having applied my patch to separate vif disconnect and free, I ran into a
> BUG when testing resume from S3 with a Windows frontend because the vif task
> pointer was not cleared by xenvif_disconnect() and so a double call to this
> function tries to stop the thread twice.
Or it is better to do more implements in windows netfront? For example,
when the windows vm hibernates, disconnect the vif as required by
netback: connect-> closing-> closed.
Thanks
Annie
> Rather than applying a point fix for that issue it seems better to introduce
> a boolean to indicate whether the vif is connected or not such that repeated
> calls to either xenvif_connect() or xenvif_disconnect() behave appropriately.
>
> Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> Cc: David Vrabel <david.vrabel@citrix.com>
> Cc: Wei Liu <wei.liu2@citrix.com>
> Cc: Ian Campbell <ian.campbell@citrix.com>
> ---
> drivers/net/xen-netback/common.h | 1 +
> drivers/net/xen-netback/interface.c | 24 +++++++++++++-----------
> 2 files changed, 14 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/net/xen-netback/common.h b/drivers/net/xen-netback/common.h
> index 5715318..860d92c 100644
> --- a/drivers/net/xen-netback/common.h
> +++ b/drivers/net/xen-netback/common.h
> @@ -169,6 +169,7 @@ struct xenvif {
>
> /* Miscellaneous private stuff. */
> struct net_device *dev;
> + bool connected;
> };
>
> static inline struct xenbus_device *xenvif_to_xenbus_device(struct xenvif *vif)
> diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c
> index 01bb854..94b47f5 100644
> --- a/drivers/net/xen-netback/interface.c
> +++ b/drivers/net/xen-netback/interface.c
> @@ -366,7 +366,7 @@ int xenvif_connect(struct xenvif *vif, unsigned long tx_ring_ref,
> int err = -ENOMEM;
>
> /* Already connected through? */
> - if (vif->tx_irq)
> + if (vif->connected)
> return 0;
>
> err = xenvif_map_frontend_rings(vif, tx_ring_ref, rx_ring_ref);
> @@ -425,6 +425,7 @@ int xenvif_connect(struct xenvif *vif, unsigned long tx_ring_ref,
>
> wake_up_process(vif->task);
>
> + vif->connected = 1;
> return 0;
>
> err_rx_unbind:
> @@ -453,23 +454,24 @@ void xenvif_carrier_off(struct xenvif *vif)
>
> void xenvif_disconnect(struct xenvif *vif)
> {
> + if (!vif->connected)
> + return;
> +
> if (netif_carrier_ok(vif->dev))
> xenvif_carrier_off(vif);
>
> - if (vif->tx_irq) {
> - if (vif->tx_irq == vif->rx_irq)
> - unbind_from_irqhandler(vif->tx_irq, vif);
> - else {
> - unbind_from_irqhandler(vif->tx_irq, vif);
> - unbind_from_irqhandler(vif->rx_irq, vif);
> - }
> - vif->tx_irq = 0;
> + if (vif->tx_irq == vif->rx_irq)
> + unbind_from_irqhandler(vif->tx_irq, vif);
> + else {
> + unbind_from_irqhandler(vif->tx_irq, vif);
> + unbind_from_irqhandler(vif->rx_irq, vif);
> }
>
> - if (vif->task)
> - kthread_stop(vif->task);
> + kthread_stop(vif->task);
>
> xenvif_unmap_frontend_rings(vif);
> +
> + vif->connected = 0;
> }
>
> void xenvif_free(struct xenvif *vif)
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox