* [PATCH net-next-2.6 v6 11/12] net-caif: add CAIF documentation
From: sjur.brandeland @ 2010-03-01 12:12 UTC (permalink / raw)
To: netdev, davem, marcel
Cc: daniel.martensson, kaber, stefano.babic, randy.dunlap,
Sjur Braendeland
In-Reply-To: <1267445559-1911-11-git-send-email-sjur.brandeland@stericsson.com>
From: Sjur Braendeland <sjur.brandeland@stericsson.com>
Documentation of the CAIF Protocol.
Signed-off-by: Sjur Braendeland <sjur.brandeland@stericsson.com>
---
Documentation/networking/caif/Linux-CAIF.txt | 212 ++++++++++++++++++++++++++
Documentation/networking/caif/README | 110 +++++++++++++
2 files changed, 322 insertions(+), 0 deletions(-)
diff --git a/Documentation/networking/caif/Linux-CAIF.txt b/Documentation/networking/caif/Linux-CAIF.txt
new file mode 100644
index 0000000..7fe7a9a
--- /dev/null
+++ b/Documentation/networking/caif/Linux-CAIF.txt
@@ -0,0 +1,212 @@
+Linux CAIF
+===========
+copyright (C) ST-Ericsson AB 2010
+Author: Sjur Brendeland/ sjur.brandeland@stericsson.com
+License terms: GNU General Public License (GPL) version 2
+
+
+Introduction
+------------
+CAIF is a MUX protocol used by ST-Ericsson cellular modems for
+communication between Modem and host. The host processes can open virtual AT
+channels, initiate GPRS Data connections, Video channels and Utility Channels.
+The Utility Channels are general purpose pipes between modem and host.
+
+ST-Ericsson modems support a number of transports between modem
+and host. Currently, UART and Loopback are available for Linux.
+
+
+Architecture:
+------------
+The implementation of CAIF is divided into:
+* CAIF Socket Layer, Kernel API, and Net Device.
+* CAIF Core Protocol Implementation
+* CAIF Link Layer, implemented as NET devices.
+
+
+ RTNL
+ !
+ ! +------+ +------+ +------+
+ ! +------+! +------+! +------+!
+ ! ! Sock !! !Kernel!! ! Net !!
+ ! ! API !+ ! API !+ ! Dev !+ <- CAIF Client APIs
+ ! +------+ +------! +------+
+ ! ! ! !
+ ! +----------!----------+
+ ! +------+ <- CAIF Protocol Implementation
+ +-------> ! CAIF !
+ ! Core !
+ +------+
+ +--------!--------+
+ ! !
+ +------+ +-----+
+ ! ! ! TTY ! <- Link Layer (Net Devices)
+ +------+ +-----+
+
+
+Using the Kernel API
+----------------------
+The Kernel API is used for accessing CAIF channels from the
+kernel.
+The user of the API has to implement two callbacks for receive
+and control.
+The receive callback gives a CAIF packet as a SKB. The control
+callback will
+notify of channel initialization complete, and flow-on/flow-
+off.
+
+
+ struct caif_device caif_dev = {
+ .caif_config = {
+ .name = "MYDEV"
+ .type = CAIF_CHTY_AT
+ }
+ .receive_cb = my_receive,
+ .control_cb = my_control,
+ };
+ caif_add_device(&caif_dev);
+ caif_transmit(&caif_dev, skb);
+
+See the caif_kernel.h for details about the CAIF kernel API.
+
+
+I M P L E M E N T A T I O N
+===========================
+===========================
+
+CAIF Core Protocol Layer
+=========================================
+
+CAIF Core layer implements the CAIF protocol as defined by ST-Ericsson.
+It implements the CAIF protocol stack in a layered approach, where
+each layer described in the specification is implemented as a separate layer.
+The architecture is inspired by the design patterns "Protocol Layer" and
+"Protocol Packet".
+
+== CAIF structure ==
+The Core CAIF implementation contains:
+ - Simple implementation of CAIF.
+ - Layered architecture (a la Streams), each layer in the CAIF
+ specification is implemented in a separate c-file.
+ - Clients must implement PHY layer to access physical HW
+ with receive and transmit functions.
+ - Clients must call configuration function to add PHY layer.
+ - Clients must implement CAIF layer to consume/produce
+ CAIF payload with receive and transmit functions.
+ - Clients must call configuration function to add and connect the
+ Client layer.
+ - When receiving / transmitting CAIF Packets (cfpkt), ownership is passed
+ to the called function (except for framing layers' receive functions
+ or if a transmit function returns an error, in which case the caller
+ must free the packet).
+
+Layered Architecture
+--------------------
+The CAIF protocol can be divided into two parts: Support functions and Protocol
+Implementation. The support functions include:
+
+ - CFPKT CAIF Packet. Implementation of CAIF Protocol Packet. The
+ CAIF Packet has functions for creating, destroying and adding content
+ and for adding/extracting header and trailers to protocol packets.
+
+ - CFLST CAIF list implementation.
+
+ - CFGLUE CAIF Glue. Contains OS Specifics, such as memory
+ allocation, endianness, etc.
+
+The CAIF Protocol implementation contains:
+
+ - CFCNFG CAIF Configuration layer. Configures the CAIF Protocol
+ Stack and provides a Client interface for adding Link-Layer and
+ Driver interfaces on top of the CAIF Stack.
+
+ - CFCTRL CAIF Control layer. Encodes and Decodes control messages
+ such as enumeration and channel setup. Also matches request and
+ response messages.
+
+ - CFSERVL General CAIF Service Layer functionality; handles flow
+ control and remote shutdown requests.
+
+ - CFVEI CAIF VEI layer. Handles CAIF AT Channels on VEI (Virtual
+ External Interface). This layer encodes/decodes VEI frames.
+
+ - CFDGML CAIF Datagram layer. Handles CAIF Datagram layer (IP
+ traffic), encodes/decodes Datagram frames.
+
+ - CFMUX CAIF Mux layer. Handles multiplexing between multiple
+ physical bearers and multiple channels such as VEI, Datagram, etc.
+ The MUX keeps track of the existing CAIF Channels and
+ Physical Instances and selects the apropriate instance based
+ on Channel-Id and Physical-ID.
+
+ - CFFRML CAIF Framing layer. Handles Framing i.e. Frame length
+ and frame checksum.
+
+ - CFSERL CAIF Serial layer. Handles concatenation/split of frames
+ into CAIF Frames with correct length.
+
+
+
+ +---------+
+ | Config |
+ | CFCNFG |
+ +---------+
+ !
+ +---------+ +---------+ +---------+
+ | AT | | Control | | Datagram|
+ | CFVEIL | | CFCTRL | | CFDGML |
+ +---------+ +---------+ +---------+
+ \_____________!______________/
+ !
+ +---------+
+ | MUX |
+ | |
+ +---------+
+ _____!_____
+ / \
+ +---------+ +---------+
+ | CFFRML | | CFFRML |
+ | Framing | | Framing |
+ +---------+ +---------+
+ ! !
+ +---------+ +---------+
+ | | | Serial |
+ | | | CFSERL |
+ +---------+ +---------+
+
+
+In this layered approach the following "rules" apply.
+ - All layers embed the same structure "struct cflayer"
+ - A layer does not depend on any other layer's private data.
+ - Layers are stacked by setting the pointers
+ layer->up , layer->dn
+ - In order to send data upwards, each layer should do
+ layer->up->receive(layer->up, packet);
+ - In order to send data downwards, each layer should do
+ layer->dn->transmit(layer->dn, packet);
+
+
+Linux Driver Implementation
+===========================
+
+Linux GPRS Net Device and CAIF socket are implemented on top of the
+CAIF Core protocol. The Net device and CAIF socket have an instance of
+'struct cflayer', just like the CAIF Core protocol stack.
+Net device and Socket implement the 'receive()' function defined by
+'struct cflayer', just like the rest of the CAIF stack. In this way, transmit and
+receive of packets is handled as by the rest of the layers: the 'dn->transmit()'
+function is called in order to transmit data.
+
+The layer on top of the CAIF Core implementation is
+sometimes referred to as the "Client layer".
+
+
+Configuration of Link Layer
+---------------------------
+The Link Layer is implemented as Linux net devices (struct net_device).
+Payload handling and registration is done using standard Linux mechanisms.
+
+The CAIF Protocol relies on a loss-less link layer without implementing
+retransmission. This implies that packet drops must not happen.
+Therefore a flow-control mechanism is implemented where the physical
+interface can initiate flow stop for all CAIF Channels.
diff --git a/Documentation/networking/caif/README b/Documentation/networking/caif/README
new file mode 100644
index 0000000..f11cea3
--- /dev/null
+++ b/Documentation/networking/caif/README
@@ -0,0 +1,110 @@
+Copyright (C) ST-Ericsson AB 2010
+Author: Sjur Brendeland/ sjur.brandeland@stericsson.com
+License terms: GNU General Public License (GPL) version 2
+
+=== Start ===
+If you have compiled CAIF for modules do:
+
+$modprobe crc_ccitt
+$modprobe caif
+$modprobe caif_socket
+$modprobe chnl_net
+
+
+=== Preparing the setup with a STE modem ===
+
+If you are working on integration of CAIF you should make sure
+that the kernel is built with module support.
+
+There are some things that need to be tweaked to get the host TTY correctly
+set up to talk to the modem.
+Since the CAIF stack is running in the kernel and we want to use the existing
+TTY, we are installing our physical serial driver as a line discipline above
+the TTY device.
+
+To achieve this we need to install the N_CAIF ldisc from user space.
+The benefit is that we can hook up to any TTY.
+
+The use of Start-of-frame-extension (STX) must also be set as
+module parameter "ser_use_stx".
+
+Normally Frame Checksum is always used on UART, but this is also provided as a
+module parameter "ser_use_fcs".
+
+$ modprobe caif_serial ser_ttyname=/dev/ttyS0 ser_use_stx=yes
+$ ifconfig caif_ttyS0 up
+
+PLEASE NOTE: There is a limitation in Android shell.
+ It only accepts one argument to insmod/modprobe!
+
+=== Trouble shooting ===
+
+There are debugfs parameters provided for serial communication.
+/sys/kernel/debug/caif_serial/<tty-name>/
+
+* ser_state: Prints the bit-mask status where
+ - 0x02 means SENDING, this is a transient state.
+ - 0x04 means TX_COMPLETE, i.e. a frame has been sent by the tty
+ - 0x10 means FLOW_OFF_SENT, i.e. the previous frame has not been sent
+ and is blocking further send operation. Flow OFF has been propagated
+ to all CAIF Channels using this TTY.
+
+* tty_status: Prints the bit-mask tty status information
+ - 0x01 - tty->warned is on.
+ - 0x02 - tty->low_latency is on.
+ - 0x04 - tty->packed is on.
+ - 0x08 - tty->flow_stopped is on.
+ - 0x10 - tty->hw_stopped is on.
+ - 0x20 - tty->stopped is on.
+
+* last_tx_msg: Binary blob Prints the last transmitted frame.
+ This can be printed with
+ $od --format=x1 /sys/kernel/debug/caif_serial/<tty>/last_rx_msg.
+ The first two tx messages sent look like this. Note: The initial
+ byte 02 is start of frame extension (STX) used for re-syncing
+ upon errors.
+
+ - Enumeration:
+ 0000000 02 05 00 00 03 01 d2 02
+ | | | | | |
+ STX(1) | | | |
+ Length(2)| | |
+ Control Channel(1)
+ Command:Enumeration(1)
+ Link-ID(1)
+ Checksum(2)
+ - Channel Setup:
+ 0000000 02 07 00 00 00 21 a1 00 48 df
+ | | | | | | | |
+ STX(1) | | | | | |
+ Length(2)| | | | |
+ Control Channel(1)
+ Command:Channel Setup(1)
+ Channel Type(1)
+ Priority and Link-ID(1)
+ Endpoint(1)
+ Checksum(2)
+
+* last_rx_msg: Prints the last transmitted frame.
+ The RX messages for LinkSetup look almost identical but they have the
+ bit 0x20 set in the command bit, and Channel Setup has added one byte
+ before Checksum containing Channel ID.
+ NOTE: Several CAIF Messages might be concatenated. The maximum debug
+ buffer size is 128 bytes.
+
+== Error Scenarios:
+- last_tx_msg contains channel setup message and last_rx_msg is empty ->
+ The host seems to be able to send over the UART, at least the CAIF ldisc get
+ notified that sending is completed.
+
+- last_tx_msg contains enumeration message and last_rx_msg is empty ->
+ The host is not able to send the message from UART, the tty has not been
+ able to complete the transmit operation.
+
+- if /sys/kernel/debug/caif_serial/<tty>/tty_status is non-zero there
+ might be problems transmitting over UART.
+ E.g. host and modem wiring is not correct you will typically see
+ tty_status = 0x10 (hw_stopped) and ser_state = 0x10 (FLOW_OFF_SENT).
+ You will probably see the enumeration message in last_tx_message
+ and empty last_rx_message.
+
--
1.6.3.3
^ permalink raw reply related
* [PATCH net-next-2.6 v6 12/12] net-caif-driver: add CAIF serial driver (ldisc)
From: sjur.brandeland @ 2010-03-01 12:12 UTC (permalink / raw)
To: netdev, davem, marcel
Cc: daniel.martensson, kaber, stefano.babic, randy.dunlap,
Sjur Braendeland
In-Reply-To: <1267445559-1911-12-git-send-email-sjur.brandeland@stericsson.com>
From: Sjur Braendeland <sjur.brandeland@stericsson.com>
Add CAIF Serial driver. This driver is implemented as a line discipline.
caif_serial uses the following module parameters:
ser_use_stx - specifies if STart of frame eXtension is in use.
ser_loop - sets the interface in loopback mode.
Signed-off-by: Sjur Braendeland <sjur.brandeland@stericsson.com>
---
drivers/net/Kconfig | 2 +
drivers/net/Makefile | 1 +
drivers/net/caif/Kconfig | 24 ++
drivers/net/caif/Makefile | 14 ++
drivers/net/caif/caif_serial.c | 463 ++++++++++++++++++++++++++++++++++++++++
include/linux/tty.h | 4 +-
6 files changed, 506 insertions(+), 2 deletions(-)
create mode 100644 drivers/net/caif/Kconfig
create mode 100644 drivers/net/caif/Makefile
create mode 100644 drivers/net/caif/caif_serial.c
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index dd9a09c..c2e670c 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -2789,6 +2789,8 @@ source "drivers/ieee802154/Kconfig"
source "drivers/s390/net/Kconfig"
+source "drivers/net/caif/Kconfig"
+
config XEN_NETDEV_FRONTEND
tristate "Xen network device frontend driver"
depends on XEN
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index ad1346d..b7ffa35 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -285,5 +285,6 @@ obj-$(CONFIG_VIRTIO_NET) += virtio_net.o
obj-$(CONFIG_SFC) += sfc/
obj-$(CONFIG_WIMAX) += wimax/
+obj-$(CONFIG_CAIF) += caif/
obj-$(CONFIG_OCTEON_MGMT_ETHERNET) += octeon/
diff --git a/drivers/net/caif/Kconfig b/drivers/net/caif/Kconfig
new file mode 100644
index 0000000..504b90a
--- /dev/null
+++ b/drivers/net/caif/Kconfig
@@ -0,0 +1,24 @@
+#
+# CAIF physical drivers
+#
+
+if CAIF
+
+comment "CAIF transport drivers"
+
+config CAIF_TTY
+ tristate "CAIF TTY transport driver"
+ default n
+ ---help---
+ The CAIF TTY transport driver.
+
+if CAIF_TTY
+config CAIF_TTY_NOFCS
+ bool "Don't use checksum for CAIF TTY transport driver"
+ default n
+ ---help---
+ If the CAIF transport driver is reliable checksumming is
+ not needed.
+endif # CAIF_TTY
+
+endif # CAIF
diff --git a/drivers/net/caif/Makefile b/drivers/net/caif/Makefile
new file mode 100644
index 0000000..01784a0
--- /dev/null
+++ b/drivers/net/caif/Makefile
@@ -0,0 +1,14 @@
+ifeq ($(CONFIG_CAIF_DEBUG),1)
+CAIF_DBG_FLAGS := -DDEBUG
+endif
+
+KBUILD_EXTRA_SYMBOLS=net/caif/Module.symvers
+
+ccflags-y := $(CAIF_FLAGS) $(CAIF_DBG_FLAGS)
+clean-dirs:= .tmp_versions
+clean-files:= Module.symvers modules.order *.cmd *~ \
+
+# Serial interface
+obj-$(CONFIG_CAIF_TTY) += caif_serial.o
+
+
diff --git a/drivers/net/caif/caif_serial.c b/drivers/net/caif/caif_serial.c
new file mode 100644
index 0000000..e5b19fa
--- /dev/null
+++ b/drivers/net/caif/caif_serial.c
@@ -0,0 +1,463 @@
+/*
+ * Copyright (C) ST-Ericsson AB 2010
+ * Author: Sjur Brendeland / sjur.brandeland@stericsson.com
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#include <linux/init.h>
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/types.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/rtnetlink.h>
+#include <linux/tty.h>
+#include <linux/file.h>
+#include <linux/if_arp.h>
+#include <net/caif/caif_device.h>
+#include <net/caif/cfcnfg.h>
+#include <linux/err.h>
+#include <linux/debugfs.h>
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Sjur Brendeland<sjur.brandeland@stericsson.com>");
+MODULE_DESCRIPTION("CAIF serial device TTY line discipline");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_LDISC(N_CAIF);
+
+
+#define CAIF_SENDING 1 /* Bit 1 = 0x02*/
+#define CAIF_UART_TX_COMPLETED 2 /* Bit 2 = 0x04 */
+#define CAIF_FLOW_OFF_SENT 4 /* Bit 4 = 0x10 */
+
+#define MAX_WRITE_CHUNK 4096
+#define ON 1
+#define OFF 0
+#define CAIF_MAX_MTU 4096
+
+
+/*This list is protected by the rtnl lock. */
+static LIST_HEAD(ser_list);
+
+static int ser_loop;
+module_param(ser_loop, bool, S_IRUGO);
+MODULE_PARM_DESC(ser_loop, "Run in simulated loopback mode.");
+
+static int ser_use_stx = 1;
+module_param(ser_use_stx, bool, S_IRUGO);
+MODULE_PARM_DESC(ser_use_stx, "STX enabled or not.");
+
+static int ser_use_fcs = 1;
+
+module_param(ser_use_fcs, bool, S_IRUGO);
+MODULE_PARM_DESC(ser_use_fcs, "FCS enabled or not.");
+
+static int ser_write_chunk = MAX_WRITE_CHUNK;
+module_param(ser_write_chunk, int, S_IRUGO);
+
+MODULE_PARM_DESC(ser_write_chunk, "Maximum size of data written to UART.");
+
+static struct dentry *debugfsdir;
+
+static int caif_net_open(struct net_device *dev);
+static int caif_net_close(struct net_device *dev);
+
+struct ser_device {
+ struct caif_dev_common common;
+ struct list_head node;
+ struct net_device *dev;
+ struct sk_buff_head head;
+ struct tty_struct *tty;
+ bool tx_started;
+ unsigned long state;
+ char *tty_name;
+#ifdef CONFIG_DEBUG_FS
+ struct dentry *debugfs_tty_dir;
+ struct debugfs_blob_wrapper tx_blob;
+ struct debugfs_blob_wrapper rx_blob;
+ u8 rx_data[128];
+ u8 tx_data[128];
+ u8 tty_status;
+
+#endif
+};
+
+static int ser_phy_tx(struct ser_device *ser, struct sk_buff *skb);
+static void caifdev_setup(struct net_device *dev);
+static void ldisc_tx_wakeup(struct tty_struct *tty);
+#ifdef CONFIG_DEBUG_FS
+static inline void update_tty_status(struct ser_device *ser)
+{
+ ser->tty_status =
+ ser->tty->stopped << 5 |
+ ser->tty->hw_stopped << 4 |
+ ser->tty->flow_stopped << 3 |
+ ser->tty->packet << 2 |
+ ser->tty->low_latency << 1 |
+ ser->tty->warned;
+}
+static inline void debugfs_init(struct ser_device *ser, struct tty_struct *tty)
+{
+ ser->debugfs_tty_dir =
+ debugfs_create_dir(tty->name, debugfsdir);
+ if (!IS_ERR(ser->debugfs_tty_dir)) {
+ debugfs_create_blob("last_tx_msg", S_IRUSR,
+ ser->debugfs_tty_dir,
+ &ser->tx_blob);
+
+ debugfs_create_blob("last_rx_msg", S_IRUSR,
+ ser->debugfs_tty_dir,
+ &ser->rx_blob);
+
+ debugfs_create_x32("ser_state", S_IRUSR,
+ ser->debugfs_tty_dir,
+ (u32 *)&ser->state);
+
+ debugfs_create_x8("tty_status", S_IRUSR,
+ ser->debugfs_tty_dir,
+ &ser->tty_status);
+
+ }
+ ser->tx_blob.data = ser->tx_data;
+ ser->tx_blob.size = 0;
+ ser->rx_blob.data = ser->rx_data;
+ ser->rx_blob.size = 0;
+}
+
+static inline void debugfs_deinit(struct ser_device *ser)
+{
+ debugfs_remove_recursive(ser->debugfs_tty_dir);
+}
+
+static inline void debugfs_rx(struct ser_device *ser, const u8 *data, int size)
+{
+ if (size > sizeof(ser->rx_data))
+ size = sizeof(ser->rx_data);
+ memcpy(ser->rx_data, data, size);
+ ser->rx_blob.data = ser->rx_data;
+ ser->rx_blob.size = size;
+}
+
+static inline void debugfs_tx(struct ser_device *ser, const u8 *data, int size)
+{
+ if (size > sizeof(ser->tx_data))
+ size = sizeof(ser->tx_data);
+ memcpy(ser->tx_data, data, size);
+ ser->tx_blob.data = ser->tx_data;
+ ser->tx_blob.size = size;
+}
+#else
+static inline void debugfs_init(struct ser_device *ser, struct tty_struct *tty)
+{
+}
+
+static inline void debugfs_deinit(struct ser_device *ser)
+{
+}
+
+static inline void update_tty_status(struct ser_device *ser)
+{
+}
+
+static inline void debugfs_rx(struct ser_device *ser, const u8 *data, int size)
+{
+}
+
+static inline void debugfs_tx(struct ser_device *ser, const u8 *data, int size)
+{
+}
+
+#endif
+
+static void ldisc_receive(struct tty_struct *tty, const u8 *data,
+ char *flags, int count)
+{
+ struct sk_buff *skb = NULL;
+ struct ser_device *ser;
+ int ret;
+ u8 *p;
+ ser = tty->disc_data;
+
+ /*
+ * Workaround for garbage at start of transmission,
+ * only enable if STX handling is not enables
+ */
+ if (!ser->common.use_stx && !ser->tx_started) {
+ dev_info(&ser->dev->dev,
+ "Bytes received before initial transmission -"
+ "bytes discarded.\n");
+ return;
+ }
+
+ BUG_ON(ser->dev == NULL);
+
+ /* Get a suitable caif packet and copy in data. */
+ skb = netdev_alloc_skb(ser->dev, count+1);
+ BUG_ON(skb == NULL);
+ p = skb_put(skb, count);
+ memcpy(p, data, count);
+
+ skb->protocol = htons(ETH_P_CAIF);
+ skb_reset_mac_header(skb);
+ skb->dev = ser->dev;
+ debugfs_rx(ser, data, count);
+ /* Push received packet up the stack. */
+ ret = netif_rx(skb);
+ if (!ret) {
+ ser->dev->stats.rx_packets++;
+ ser->dev->stats.rx_bytes += count;
+ } else
+ ++ser->dev->stats.rx_dropped;
+ update_tty_status(ser);
+}
+
+static int handle_tx(struct ser_device *ser)
+{
+ struct tty_struct *tty;
+ struct sk_buff *skb;
+ char *buf;
+ int tty_wr, len, room, pktlen;
+ tty = ser->tty;
+
+ /*
+ * NOTE: This workaround is not really needed when STX is enabled.
+ * Remove?
+ */
+ if (ser->tx_started == false)
+ ser->tx_started = true;
+
+ if (test_and_set_bit(CAIF_SENDING, &ser->state)) {
+ set_bit(CAIF_UART_TX_COMPLETED, &ser->state);
+ return 0;
+ }
+
+ do {
+ skb = skb_peek(&ser->head);
+ if (skb != NULL && skb->len == 0) {
+ struct sk_buff *tmp;
+ tmp = skb_dequeue(&ser->head);
+ BUG_ON(tmp != skb);
+ kfree_skb(skb);
+ skb = skb_peek(&ser->head);
+ }
+
+ if (skb == NULL) {
+ if (test_and_clear_bit(
+ CAIF_FLOW_OFF_SENT,
+ &ser->state)) {
+ if (ser->common.flowctrl != NULL)
+ ser->common.flowctrl(ser->dev, ON);
+ }
+ break;
+ }
+
+
+ buf = skb->data;
+ pktlen = len = skb->len;
+
+ clear_bit(CAIF_UART_TX_COMPLETED, &ser->state);
+ room = tty_write_room(tty);
+ if (room > ser_write_chunk)
+ room = ser_write_chunk;
+
+ if (len > room)
+ len = room;
+ debugfs_tx(ser, buf, len);
+ if (!ser_loop) {
+ tty_wr = tty->ops->write(tty, buf, len);
+ } else {
+ tty_wr = len;
+ ldisc_receive(tty, buf, 0, len);
+ }
+ ser->dev->stats.tx_packets++;
+ ser->dev->stats.tx_bytes += tty_wr;
+ if (tty_wr > 0)
+ skb_pull(skb, tty_wr);
+
+ if (ser_loop)
+ ldisc_tx_wakeup(tty);
+ update_tty_status(ser);
+
+ } while (test_bit(CAIF_UART_TX_COMPLETED, &(ser->state)));
+
+ clear_bit(CAIF_SENDING, &ser->state);
+ return 0;
+}
+
+static int ser_phy_tx(struct ser_device *ser, struct sk_buff *skb)
+{
+ if (skb_peek(&ser->head) != NULL) {
+ if (!test_and_set_bit(CAIF_FLOW_OFF_SENT, &ser->state)
+ && ser->common.flowctrl != NULL)
+ ser->common.flowctrl(ser->dev, OFF);
+ }
+ skb_queue_tail(&ser->head, skb);
+ if (!test_bit(CAIF_SENDING, &ser->state))
+ handle_tx(ser);
+ update_tty_status(ser);
+ return 0;
+}
+
+static int caif_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ struct ser_device *ser;
+ if (!dev)
+ return -EINVAL;
+ ser = netdev_priv(dev);
+ return ser_phy_tx(ser, skb);
+}
+
+
+static void ldisc_tx_wakeup(struct tty_struct *tty)
+{
+ struct ser_device *ser;
+ ser = tty->disc_data;
+ if (ser == NULL)
+ return;
+ set_bit(CAIF_UART_TX_COMPLETED, &ser->state);
+ if (ser->tty != tty)
+ return;
+ handle_tx(ser);
+}
+
+
+static int ldisc_open(struct tty_struct *tty)
+{
+ struct ser_device *ser;
+ struct net_device *dev;
+ char name[64];
+ int result;
+
+ sprintf(name, "caif_%s", tty->name);
+
+ dev = alloc_netdev(sizeof(*ser), name, caifdev_setup);
+
+
+ ser = netdev_priv(dev);
+ ser->tty = tty;
+ ser->dev = dev;
+ debugfs_init(ser, tty);
+ tty->receive_room = N_TTY_BUF_SIZE;
+ tty->disc_data = ser;
+
+ set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
+ rtnl_lock();
+ result = register_netdevice(dev);
+ if (result) {
+ rtnl_unlock();
+ free_netdev(dev);
+ return -ENODEV;
+ }
+
+ list_add(&ser->node, &ser_list);
+ rtnl_unlock();
+ netif_stop_queue(dev);
+ update_tty_status(ser);
+ return 0;
+}
+
+static void ldisc_close(struct tty_struct *tty)
+{
+ struct ser_device *ser = tty->disc_data;
+ /* Remove may be called inside or outside of rtnl_lock */
+ int islocked = rtnl_is_locked();
+ if (!islocked)
+ rtnl_lock();
+ /* device is freed automagically by net-sysfs */
+ dev_close(ser->dev);
+ unregister_netdevice(ser->dev);
+ list_del(&ser->node);
+ debugfs_deinit(ser);
+ if (!islocked)
+ rtnl_unlock();
+}
+
+/* The line discipline structure. */
+static struct tty_ldisc_ops caif_ldisc = {
+ .owner = THIS_MODULE,
+ .magic = TTY_LDISC_MAGIC,
+ .name = "n_caif",
+ .open = ldisc_open,
+ .close = ldisc_close,
+ .receive_buf = ldisc_receive,
+ .write_wakeup = ldisc_tx_wakeup
+};
+
+static int register_ldisc(void)
+{
+ int result;
+ result = tty_register_ldisc(N_CAIF, &caif_ldisc);
+ if (result < 0) {
+ pr_err("cannot register CAIF ldisc=%d err=%d\n", N_CAIF,
+ result);
+ return result;
+ }
+ return result;
+}
+
+static const struct net_device_ops netdev_ops = {
+ .ndo_open = caif_net_open,
+ .ndo_stop = caif_net_close,
+ .ndo_start_xmit = caif_xmit
+};
+static void caifdev_setup(struct net_device *dev)
+{
+ struct ser_device *serdev = netdev_priv(dev);
+ dev->features = 0;
+
+ dev->netdev_ops = &netdev_ops;
+
+ dev->type = ARPHRD_CAIF;
+ dev->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_POINTOPOINT;
+ dev->mtu = CAIF_MAX_MTU;
+ dev->hard_header_len = CAIF_NEEDED_HEADROOM;
+ dev->tx_queue_len = 0;
+ dev->destructor = free_netdev;
+ skb_queue_head_init(&serdev->head);
+ serdev->common.link_select = CAIF_LINK_LOW_LATENCY;
+ serdev->common.use_frag = true;
+ serdev->common.use_stx = ser_use_stx;
+ serdev->common.use_fcs = ser_use_fcs;
+ serdev->dev = dev;
+}
+
+static int caif_net_open(struct net_device *dev)
+{
+ struct ser_device *ser;
+ ser = netdev_priv(dev);
+ netif_wake_queue(dev);
+ return 0;
+}
+
+static int caif_net_close(struct net_device *dev)
+{
+ netif_stop_queue(dev);
+ return 0;
+}
+
+static int __init caif_ser_init(void)
+{
+ int ret;
+ ret = register_ldisc();
+ debugfsdir = debugfs_create_dir("caif_serial", NULL);
+ return ret;
+}
+
+static void __exit caif_ser_exit(void)
+{
+ struct ser_device *ser = NULL;
+ struct list_head *node;
+ struct list_head *_tmp;
+ list_for_each_safe(node, _tmp, &ser_list) {
+ ser = list_entry(node, struct ser_device, node);
+ dev_close(ser->dev);
+ unregister_netdevice(ser->dev);
+ list_del(node);
+ }
+ tty_unregister_ldisc(N_CAIF);
+ debugfs_remove_recursive(debugfsdir);
+}
+
+module_init(caif_ser_init);
+module_exit(caif_ser_exit);
diff --git a/include/linux/tty.h b/include/linux/tty.h
index ef3a294..5dd674b 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -23,7 +23,7 @@
*/
#define NR_UNIX98_PTY_DEFAULT 4096 /* Default maximum for Unix98 ptys */
#define NR_UNIX98_PTY_MAX (1 << MINORBITS) /* Absolute limit */
-#define NR_LDISCS 20
+#define NR_LDISCS 21
/* line disciplines */
#define N_TTY 0
@@ -46,8 +46,8 @@
#define N_GIGASET_M101 16 /* Siemens Gigaset M101 serial DECT adapter */
#define N_SLCAN 17 /* Serial / USB serial CAN Adaptors */
#define N_PPS 18 /* Pulse per Second */
-
#define N_V253 19 /* Codec control over voice modem */
+#define N_CAIF 20 /* CAIF protocol for talking to modems */
/*
* This character is the same as _POSIX_VDISABLE: it cannot be used as
--
1.6.3.3
^ permalink raw reply related
* Re: NETIF_F_FRAGLIST and NETIF_F_SG difference
From: Ben Hutchings @ 2010-03-01 12:58 UTC (permalink / raw)
To: raj ravi; +Cc: netdev
In-Reply-To: <de0a9dcb1003010302p2f81aa17ubdbb29bb007d50cf@mail.gmail.com>
On Mon, 2010-03-01 at 16:32 +0530, raj ravi wrote:
> Hi,
> http://lxr.linux.no/#linux+v2.6.33/include/linux/netdevice.h
> In include/linux/netdevice.h I can see two definiton for "Scatter
> Gather IO" namely NETIF_F_FRAGLIST and NETIF_F_SG
>
> Please let me know the difference between the two.... if there is no
> difference why two Macros ??
>
>
> #define NETIF_F_SG 1 /* Scatter/gather IO. */
This means the device can transmit an skb with extra data attached
through skb_shinfo(skb)->frags.
> #define NETIF_F_IP_CSUM 2 /* Can checksum TCP/UDP over IPv4. */
> #define NETIF_F_NO_CSUM 4 /* Does not require checksum. F.e. loopack. */
> #define NETIF_F_HW_CSUM 8 /* Can checksum all the packets. */
> #define NETIF_F_IPV6_CSUM 16 /* Can checksum TCP/UDP over IPV6 */
> #define NETIF_F_HIGHDMA 32 /* Can DMA to high memory. */
> #define NETIF_F_FRAGLIST 64 /* Scatter/gather IO. */
This means the device can transmit an skb with extra data attached
through skb->frags.
(I don't know why there are two ways of adding extra data. The latter
does not seem to be used often.)
Note that these flags really refer only to DMA gather. There is no need
for a feature flag for DMA scatter, since the driver controls RX buffer
allocation.
Ben.
--
Ben Hutchings, Senior Software Engineer, Solarflare Communications
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
* Re: Gianfar driver failing on MPC8641D based board
From: Martyn Welch @ 2010-03-01 13:07 UTC (permalink / raw)
To: linuxppc-dev list
Cc: Paul Gortmaker, netdev, linux-kernel, Sandeep Gopalpet, davem
In-Reply-To: <20100226213825.GA32363@oksana.dev.rtsoft.ru>
Anton Vorontsov wrote:
> diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
> index 8bd3c9f..cccb409 100644
> --- a/drivers/net/gianfar.c
> +++ b/drivers/net/gianfar.c
> @@ -2021,7 +2021,6 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
> }
>
> /* setup the TxBD length and buffer pointer for the first BD */
> - tx_queue->tx_skbuff[tx_queue->skb_curtx] = skb;
> txbdp_start->bufPtr = dma_map_single(&priv->ofdev->dev, skb->data,
> skb_headlen(skb), DMA_TO_DEVICE);
>
> @@ -2053,6 +2052,10 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
>
> txbdp_start->lstatus = lstatus;
>
> + eieio(); /* force lstatus write before tx_skbuff */
> +
> + tx_queue->tx_skbuff[tx_queue->skb_curtx] = skb;
> +
> /* Update the current skb pointer to the next entry we will use
> * (wrapping if necessary) */
> tx_queue->skb_curtx = (tx_queue->skb_curtx + 1) &
>
I can confirm 10/10 successful boots on p2020ds and mpc8641_hpcn.
Martyn
--
Martyn Welch (Principal Software Engineer) | Registered in England and
GE Intelligent Platforms | Wales (3828642) at 100
T +44(0)127322748 | Barbirolli Square, Manchester,
E martyn.welch@ge.com | M2 3AB VAT:GB 927559189
^ permalink raw reply
* Re: sparse checking prevented by "net: fix kmemcheck annotations"
From: Eric Dumazet @ 2010-03-01 13:09 UTC (permalink / raw)
To: Stefan Richter; +Cc: linux-kernel, David S. Miller, netdev
In-Reply-To: <4B8BAE79.9000609@s5r6.in-berlin.de>
Le lundi 01 mars 2010 à 13:09 +0100, Stefan Richter a écrit :
> Hi all,
>
> the post 2.6.32-rc5, pre 2.6.32-rc6 commit 14d18a81 causes a serious
> regression for sparse checks: make C=1 CF="-D__CHECK_ENDIAN__" now
> causes sparse to log
>
> include/linux/skbuff.h:357:41: error: invalid bitfield specifier for
> type restricted __be16.
>
>
> I reported this already shortly after this hit the mainline. But back
> then I didn't notice that this sparse error causes sparse to remain
> silent on all subsequent warnings in a file!
>
> We need to either change sparse to accept this bogus bit field that
> occurs in skbuff.h (__be16 protocol:16;), silently or with a warning, or
> revert this kmemcheck annotation.
>
> ("We" == preferably Eric :-)
>
> skbuff.h is included by lots of drivers, even ones that are not even
> networking drivers, notably DVB drivers. None of these drivers can be
> checked with sparse's __CHECK_ENDIAN__ at the moment.
Hi Stefan
I believe kmemcheck side effects were solved by commit e992cd9b72a18122
(kmemcheck: make bitfield annotations truly no-ops when disabled),
so there is no problem to partially revert the patch and fix this
problem.
Thanks !
[PATCH] net: fix protocol sk_buff field
Commit e992cd9b72a18 (kmemcheck: make bitfield annotations truly no-ops
when disabled) allows us to revert a workaround we did in the past to
not add holes in sk_buff structure.
This patch partially reverts commit 14d18a81b5171
(net: fix kmemcheck annotations) so that sparse doesnt complain:
include/linux/skbuff.h:357:41: error: invalid bitfield specifier for
type restricted __be16.
Reported-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
---
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index ae836fd..b40f56b 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -354,8 +354,8 @@ struct sk_buff {
ipvs_property:1,
peeked:1,
nf_trace:1;
- __be16 protocol:16;
kmemcheck_bitfield_end(flags1);
+ __be16 protocol;
void (*destructor)(struct sk_buff *skb);
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
^ permalink raw reply related
* Re: [PATCH 1/1] bnx2x: Tx barriers and locks
From: Stanislaw Gruszka @ 2010-03-01 13:33 UTC (permalink / raw)
To: Vladislav Zolotarov; +Cc: netdev, davem, eilong, Matt Carlson, Michael Chan
In-Reply-To: <1267351922.10409.2.camel@lb-tlvb-vladz>
On Sun, Feb 28, 2010 at 12:12:02PM +0200, Vladislav Zolotarov wrote:
> --- a/drivers/net/bnx2x_main.c
> +++ b/drivers/net/bnx2x_main.c
> @@ -57,8 +57,8 @@
> #include "bnx2x_init_ops.h"
> #include "bnx2x_dump.h"
>
> -#define DRV_MODULE_VERSION "1.52.1-6"
> -#define DRV_MODULE_RELDATE "2010/02/16"
> +#define DRV_MODULE_VERSION "1.52.1-7"
> +#define DRV_MODULE_RELDATE "2010/02/28"
> #define BNX2X_BC_VER 0x040200
>
> #include <linux/firmware.h>
> @@ -957,21 +957,34 @@ static int bnx2x_tx_int(struct bnx2x_fastpath *fp)
> fp->tx_pkt_cons = sw_cons;
> fp->tx_bd_cons = bd_cons;
>
> + /* Need to make the tx_bd_cons update visible to start_xmit()
> + * before checking for netif_tx_queue_stopped(). Without the
> + * memory barrier, there is a small possibility that
> + * start_xmit() will miss it and cause the queue to be stopped
> + * forever.
> + */
> + smp_wmb();
> +
> /* TBD need a thresh? */
> if (unlikely(netif_tx_queue_stopped(txq))) {
> -
> - /* Need to make the tx_bd_cons update visible to start_xmit()
> - * before checking for netif_tx_queue_stopped(). Without the
> - * memory barrier, there is a small possibility that
> - * start_xmit() will miss it and cause the queue to be stopped
> - * forever.
> + /* Taking tx_lock() is needed to prevent reenabling the queue
> + * while it's empty. This could have happen if rx_action() gets
> + * suspended in bnx2x_tx_int() after the condition before
> + * netif_tx_wake_queue(), while tx_action (bnx2x_start_xmit()):
> + *
> + * stops the queue->sees fresh tx_bd_cons->releases the queue->
> + * sends some packets consuming the whole queue again->
> + * stops the queue
> */
> - smp_mb();
> +
> + __netif_tx_lock(txq, smp_processor_id());
>
> if ((netif_tx_queue_stopped(txq)) &&
> (bp->state == BNX2X_STATE_OPEN) &&
> (bnx2x_tx_avail(fp) >= MAX_SKB_FRAGS + 3))
> netif_tx_wake_queue(txq);
> +
> + __netif_tx_unlock(txq);
> }
> return 0;
> }
There is still difference between what we have in bnx2x and bnx2/tg3
regarding memory barriers in tx_poll/start_xmit code. Mainly we have
smp_mb() in bnx2/tg3_tx_avail(), and in bnx2/tg3_tx_int() is smp_mb()
not smp_wmb(). I do not see that bnx2x is wrong, but would like to know
why there is a difference, maybe bnx2/tg3 should be changed?
Stanislaw
^ permalink raw reply
* call ((+2348056281072)) for your western union promo
From: notification @ 2010-03-01 14:21 UTC (permalink / raw)
You have been awarded with the sum of $50,000 USD by our office, as one of our
customers who use Western Union in their daily business transaction.Please
provide Mr.Dominic Johnson with the following details listed below so that
your fund will be remited to you through Western Union.
1. Name:______
2. Address________
3. Country:_______
4. Phone Number____
5. Occupation:________
6. Sex:_________________
7. Age___________________
Mr.Dominic Johnson
Tel;+2348056281072
E-mail: w.unionclaim1@w.cn
^ permalink raw reply
* [net-next-2.6 PATCH] net: convert multiple drivers to use netdev_for_each_mc_addr, part7
From: Jiri Pirko @ 2010-03-01 15:09 UTC (permalink / raw)
To: netdev; +Cc: davem
In mlx4, using char * to store mc address in private structure instead.
Signed-off-by: Jiri Pirko <jpirko@redhat.com>
---
drivers/media/dvb/dvb-core/dvb_net.c | 6 +---
drivers/net/mlx4/en_netdev.c | 49 ++++++++++++++--------------------
drivers/net/mlx4/mlx4_en.h | 3 +-
drivers/s390/net/qeth_l2_main.c | 2 +-
net/bluetooth/bnep/netdev.c | 10 +++---
5 files changed, 29 insertions(+), 41 deletions(-)
diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c
index 441c064..dba1c84 100644
--- a/drivers/media/dvb/dvb-core/dvb_net.c
+++ b/drivers/media/dvb/dvb-core/dvb_net.c
@@ -1140,7 +1140,6 @@ static void wq_set_multicast_list (struct work_struct *work)
dprintk("%s: allmulti mode\n", dev->name);
priv->rx_mode = RX_MODE_ALL_MULTI;
} else if (!netdev_mc_empty(dev)) {
- int mci;
struct dev_mc_list *mc;
dprintk("%s: set_mc_list, %d entries\n",
@@ -1149,11 +1148,8 @@ static void wq_set_multicast_list (struct work_struct *work)
priv->rx_mode = RX_MODE_MULTI;
priv->multi_num = 0;
- for (mci = 0, mc=dev->mc_list;
- mci < netdev_mc_count(dev);
- mc = mc->next, mci++) {
+ netdev_for_each_mc_addr(mc, dev)
dvb_set_mc_filter(dev, mc);
- }
}
netif_addr_unlock_bh(dev);
diff --git a/drivers/net/mlx4/en_netdev.c b/drivers/net/mlx4/en_netdev.c
index c48b0f4..7cd0933 100644
--- a/drivers/net/mlx4/en_netdev.c
+++ b/drivers/net/mlx4/en_netdev.c
@@ -160,39 +160,29 @@ static void mlx4_en_do_set_mac(struct work_struct *work)
static void mlx4_en_clear_list(struct net_device *dev)
{
struct mlx4_en_priv *priv = netdev_priv(dev);
- struct dev_mc_list *plist = priv->mc_list;
- struct dev_mc_list *next;
- while (plist) {
- next = plist->next;
- kfree(plist);
- plist = next;
- }
- priv->mc_list = NULL;
+ kfree(priv->mc_addrs);
+ priv->mc_addrs_cnt = 0;
}
static void mlx4_en_cache_mclist(struct net_device *dev)
{
struct mlx4_en_priv *priv = netdev_priv(dev);
struct dev_mc_list *mclist;
- struct dev_mc_list *tmp;
- struct dev_mc_list *plist = NULL;
-
- for (mclist = dev->mc_list; mclist; mclist = mclist->next) {
- tmp = kmalloc(sizeof(struct dev_mc_list), GFP_ATOMIC);
- if (!tmp) {
- en_err(priv, "failed to allocate multicast list\n");
- mlx4_en_clear_list(dev);
- return;
- }
- memcpy(tmp, mclist, sizeof(struct dev_mc_list));
- tmp->next = NULL;
- if (plist)
- plist->next = tmp;
- else
- priv->mc_list = tmp;
- plist = tmp;
+ char *mc_addrs;
+ int mc_addrs_cnt = netdev_mc_count(dev);
+ int i;
+
+ mc_addrs = kmalloc(mc_addrs_cnt * ETH_ALEN, GFP_ATOMIC);
+ if (!mc_addrs) {
+ en_err(priv, "failed to allocate multicast list\n");
+ return;
}
+ i = 0;
+ netdev_for_each_mc_addr(mclist, dev)
+ memcpy(mc_addrs + i++ * ETH_ALEN, mclist->dmi_addr, ETH_ALEN);
+ priv->mc_addrs = mc_addrs;
+ priv->mc_addrs_cnt = mc_addrs_cnt;
}
@@ -212,7 +202,6 @@ static void mlx4_en_do_set_multicast(struct work_struct *work)
mcast_task);
struct mlx4_en_dev *mdev = priv->mdev;
struct net_device *dev = priv->dev;
- struct dev_mc_list *mclist;
u64 mcast_addr = 0;
int err;
@@ -288,6 +277,8 @@ static void mlx4_en_do_set_multicast(struct work_struct *work)
if (err)
en_err(priv, "Failed disabling multicast filter\n");
} else {
+ int i;
+
err = mlx4_SET_MCAST_FLTR(mdev->dev, priv->port, 0,
0, MLX4_MCAST_DISABLE);
if (err)
@@ -302,8 +293,9 @@ static void mlx4_en_do_set_multicast(struct work_struct *work)
netif_tx_lock_bh(dev);
mlx4_en_cache_mclist(dev);
netif_tx_unlock_bh(dev);
- for (mclist = priv->mc_list; mclist; mclist = mclist->next) {
- mcast_addr = mlx4_en_mac_to_u64(mclist->dmi_addr);
+ for (i = 0; i < priv->mc_addrs_cnt; i++) {
+ mcast_addr =
+ mlx4_en_mac_to_u64(priv->mc_addrs + i * ETH_ALEN);
mlx4_SET_MCAST_FLTR(mdev->dev, priv->port,
mcast_addr, 0, MLX4_MCAST_CONFIG);
}
@@ -984,7 +976,6 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
priv->flags = prof->flags;
priv->tx_ring_num = prof->tx_ring_num;
priv->rx_ring_num = prof->rx_ring_num;
- priv->mc_list = NULL;
priv->mac_index = -1;
priv->msg_enable = MLX4_EN_MSG_LEVEL;
spin_lock_init(&priv->stats_lock);
diff --git a/drivers/net/mlx4/mlx4_en.h b/drivers/net/mlx4/mlx4_en.h
index 82c3ebc..b55e46c 100644
--- a/drivers/net/mlx4/mlx4_en.h
+++ b/drivers/net/mlx4/mlx4_en.h
@@ -492,7 +492,8 @@ struct mlx4_en_priv {
struct mlx4_en_perf_stats pstats;
struct mlx4_en_pkt_stats pkstats;
struct mlx4_en_port_stats port_stats;
- struct dev_mc_list *mc_list;
+ char *mc_addrs;
+ int mc_addrs_cnt;
struct mlx4_en_stat_out_mbox hw_stats;
};
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
index 51fde6f..d5bef49 100644
--- a/drivers/s390/net/qeth_l2_main.c
+++ b/drivers/s390/net/qeth_l2_main.c
@@ -619,7 +619,7 @@ static void qeth_l2_set_multicast_list(struct net_device *dev)
return;
qeth_l2_del_all_mc(card);
spin_lock_bh(&card->mclock);
- for (dm = dev->mc_list; dm; dm = dm->next)
+ netdev_for_each_mc_addr(dm, dev)
qeth_l2_add_mc(card, dm->da_addr, 0);
netdev_for_each_uc_addr(ha, dev)
diff --git a/net/bluetooth/bnep/netdev.c b/net/bluetooth/bnep/netdev.c
index b6234b7..326ab45 100644
--- a/net/bluetooth/bnep/netdev.c
+++ b/net/bluetooth/bnep/netdev.c
@@ -87,7 +87,7 @@ static void bnep_net_set_mc_list(struct net_device *dev)
memcpy(__skb_put(skb, ETH_ALEN), dev->broadcast, ETH_ALEN);
r->len = htons(ETH_ALEN * 2);
} else {
- struct dev_mc_list *dmi = dev->mc_list;
+ struct dev_mc_list *dmi;
int i, len = skb->len;
if (dev->flags & IFF_BROADCAST) {
@@ -97,12 +97,12 @@ static void bnep_net_set_mc_list(struct net_device *dev)
/* FIXME: We should group addresses here. */
- for (i = 0;
- i < netdev_mc_count(dev) && i < BNEP_MAX_MULTICAST_FILTERS;
- i++) {
+ i = 0;
+ netdev_for_each_mc_addr(dmi, dev) {
+ if (i == BNEP_MAX_MULTICAST_FILTERS)
+ break;
memcpy(__skb_put(skb, ETH_ALEN), dmi->dmi_addr, ETH_ALEN);
memcpy(__skb_put(skb, ETH_ALEN), dmi->dmi_addr, ETH_ALEN);
- dmi = dmi->next;
}
r->len = htons(skb->len - len);
}
--
1.6.6
^ permalink raw reply related
* Re: [RFC][PATCH] af_unix: Add peer inode to /proc/net/unix
From: Kenan Kalajdzic @ 2010-03-01 15:09 UTC (permalink / raw)
To: Changli Gao; +Cc: davem, netdev
In-Reply-To: <412e6f7f1002282305i1d201d76h4085220f71fc76d0@mail.gmail.com>
On Mon, Mar 01, 2010 at 03:05:50PM +0800, Changli Gao wrote:
> If there are two read requests, the system maybe locked up. please use
> unix_state_double_lock()/unix_state_double_unlock(), instead. And the
Thanks for pointing this out. The corrected patch is provided at the end.
> file isn't consistent with the old one. You'd better use a column
> title "Peer" instead of "peer=".
As far as the column name is concerned, I avoided adding a new column, since
this would break userspace programs. Instead, I reused empty space provided
within the 'Path' column to add peer inode number for unbound sockets. This
makes it easy to match client and server sockets as well as unnamed socket
pairs created with socketpair(2).
Here is an example of using the peer inode information from /proc/net/unix
to find all local X-clients:
(1) Find all X-server sockets:
# strings /proc/net/unix | grep X11
e51ec8c0: 00000002 00000000 00010000 0001 01 12318 /tmp/.X11-unix/X0
d2ae98c0: 00000003 00000000 00000000 0001 03 16077 /tmp/.X11-unix/X0
d2b38e00: 00000003 00000000 00000000 0001 03 15858 /tmp/.X11-unix/X0
d2a3bc40: 00000003 00000000 00000000 0001 03 13828 /tmp/.X11-unix/X0
d2a3b1c0: 00000003 00000000 00000000 0001 03 13816 /tmp/.X11-unix/X0
d2909380: 00000003 00000000 00000000 0001 03 13802 /tmp/.X11-unix/X0
d299da80: 00000003 00000000 00000000 0001 03 13728 /tmp/.X11-unix/X0
d299d540: 00000003 00000000 00000000 0001 03 13722 /tmp/.X11-unix/X0
d293f380: 00000003 00000000 00000000 0001 03 13715 /tmp/.X11-unix/X0
d2957700: 00000003 00000000 00000000 0001 03 13644 /tmp/.X11-unix/X0
d291fa80: 00000003 00000000 00000000 0001 03 13585 /tmp/.X11-unix/X0
d290de00: 00000003 00000000 00000000 0001 03 13573 /tmp/.X11-unix/X0
d9fea700: 00000003 00000000 00000000 0001 03 13550 /tmp/.X11-unix/X0
d9fea000: 00000003 00000000 00000000 0001 03 13531 /tmp/.X11-unix/X0
d28b5e00: 00000003 00000000 00000000 0001 03 13465 /tmp/.X11-unix/X0
e541e540: 00000003 00000000 00000000 0001 03 13277 /tmp/.X11-unix/X0
d2898e00: 00000003 00000000 00000000 0001 03 13269 /tmp/.X11-unix/X0
e42ee000: 00000003 00000000 00000000 0001 03 12376 /tmp/.X11-unix/X0
(2) Using inode number of each of the listed X-server sockets, find the
corresponding peer socket. Here we make use of the fact that the peer
inode number is recorded within the 'Path' column of client sockets:
# strings /proc/net/unix | egrep 'peer=(12318|16077|15858|13828|13816|13802'\
> '|13728|13722|13715|13644|13585|13573|13550|13531|13465|13277|13269|12376)$'
d2ae9700: 00000003 00000000 00000000 0001 03 16076 peer=16077
d2b38c40: 00000003 00000000 00000000 0001 03 15857 peer=15858
d2a3ba80: 00000003 00000000 00000000 0001 03 13827 peer=13828
d2a3b000: 00000003 00000000 00000000 0001 03 13815 peer=13816
d29091c0: 00000003 00000000 00000000 0001 03 13801 peer=13802
d299d8c0: 00000003 00000000 00000000 0001 03 13727 peer=13728
d299d380: 00000003 00000000 00000000 0001 03 13721 peer=13722
d293fc40: 00000003 00000000 00000000 0001 03 13714 peer=13715
d29578c0: 00000003 00000000 00000000 0001 03 13643 peer=13644
d291f8c0: 00000003 00000000 00000000 0001 03 13584 peer=13585
d290dc40: 00000003 00000000 00000000 0001 03 13572 peer=13573
d9fea540: 00000003 00000000 00000000 0001 03 13549 peer=13550
d28a98c0: 00000003 00000000 00000000 0001 03 13530 peer=13531
d9fe5e00: 00000003 00000000 00000000 0001 03 13464 peer=13465
e541e700: 00000003 00000000 00000000 0001 03 13276 peer=13277
d28988c0: 00000003 00000000 00000000 0001 03 13268 peer=13269
e51ece00: 00000003 00000000 00000000 0001 03 12320 peer=12376
(3) Using the peer inode numbers, find the corresponding process(es)
through /proc/<PID>/fd/*:
# ls -l /proc/*/fd/* 2>/dev/null | egrep 'socket:.(16076|'\
> '15857|13827|13815|13801|13727|13721|13714|13643|13584|'\
> '13572|13549|13530|13464|13276|13268|12320)'
lr-x------ 1 root root 64 Mar 1 15:07 /proc/4101/fd/3 -> socket:[12320]
lrwx------ 1 root root 64 Mar 1 15:20 /proc/4243/fd/3 -> socket:[13276]
lrwx------ 1 root root 64 Mar 1 15:24 /proc/4311/fd/4 -> socket:[13268]
lrwx------ 1 root root 64 Mar 1 15:24 /proc/4323/fd/3 -> socket:[13464]
lrwx------ 1 root root 64 Mar 1 15:24 /proc/4338/fd/12 -> socket:[13530]
lrwx------ 1 root root 64 Mar 1 15:24 /proc/4342/fd/3 -> socket:[13549]
lrwx------ 1 root root 64 Mar 1 15:24 /proc/4344/fd/3 -> socket:[13572]
lrwx------ 1 root root 64 Mar 1 15:24 /proc/4351/fd/3 -> socket:[13584]
lrwx------ 1 root root 64 Mar 1 15:24 /proc/4353/fd/3 -> socket:[13643]
lrwx------ 1 root root 64 Mar 1 15:24 /proc/4371/fd/8 -> socket:[13721]
lrwx------ 1 root root 64 Mar 1 15:24 /proc/4374/fd/3 -> socket:[13727]
lrwx------ 1 root root 64 Mar 1 15:24 /proc/4387/fd/4 -> socket:[13827]
lrwx------ 1 root root 64 Mar 1 15:24 /proc/4389/fd/3 -> socket:[13815]
lrwx------ 1 root root 64 Mar 1 15:24 /proc/4393/fd/3 -> socket:[13801]
lrwx------ 1 root root 64 Mar 1 15:24 /proc/4401/fd/3 -> socket:[13714]
lrwx------ 1 root root 64 Mar 1 15:24 /proc/4477/fd/3 -> socket:[15857]
lrwx------ 1 root root 64 Mar 1 15:24 /proc/4488/fd/3 -> socket:[16076]
(4) Finally, use the PIDs obtained in previous step to get a readable
list of X-clients:
# ps -eo pid,args | awk '$1 ~ "^(4101|4243|4311|4323|4338|4342|'\
> '4344|4351|4353|4371|4374|4387|4389|4393|4401|4477|4488)$"'
4101 /usr/sbin/gdm-binary -nodaemon
4243 /usr/bin/gnome-session
4311 /usr/bin/dbus-launch --exit-with-session /etc/X11/xinit/Xclients
4323 /usr/libexec/gnome-settings-daemon
4338 metacity --sm-client-id=default1
4342 gnome-panel --sm-client-id default2
4344 nautilus --no-default-window --sm-client-id default3
4351 gnome-volume-manager --sm-client-id default5
4353 eggcups --sm-client-id default4
4371 ./escd --key_Inserted="/usr/bin/esc" --on_Signal="/usr/bin/esc"
4374 bt-applet --sm-disable
4387 /usr/bin/python -tt /usr/bin/puplet
4389 nm-applet --sm-disable
4393 pam-panel-icon --sm-client-id default0
4401 gnome-power-manager
4477 gnome-screensaver
4488 gnome-terminal
Signed-off-by: Kenan Kalajdzic <kenan@unix.ba>
---
net/unix/af_unix.c | 13 ++++++++++---
1 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index f255119..cee957a 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -2157,9 +2157,14 @@ static int unix_seq_show(struct seq_file *seq, void *v)
seq_puts(seq, "Num RefCount Protocol Flags Type St "
"Inode Path\n");
else {
- struct sock *s = v;
+ struct sock *s = v, *peer;
struct unix_sock *u = unix_sk(s);
+
unix_state_lock(s);
+ peer = unix_peer(s);
+ unix_state_unlock(s);
+
+ unix_state_double_lock(s, peer);
seq_printf(seq, "%p: %08X %08X %08X %04X %02X %5lu",
s,
@@ -2186,8 +2191,10 @@ static int unix_seq_show(struct seq_file *seq, void *v)
}
for ( ; i < len; i++)
seq_putc(seq, u->addr->name->sun_path[i]);
- }
- unix_state_unlock(s);
+ } else if (peer)
+ seq_printf(seq, " peer=%lu", sock_i_ino(peer));
+
+ unix_state_double_unlock(s, peer);
seq_putc(seq, '\n');
}
--
1.6.4
^ permalink raw reply related
* [ANNOUNCE]: Release of iptables-1.4.7
From: Patrick McHardy @ 2010-03-01 15:20 UTC (permalink / raw)
To: Netfilter Development Mailinglist, Linux Netdev List,
netfilter-announce
[-- Attachment #1: Type: text/plain, Size: 519 bytes --]
The netfilter coreteam presents:
iptables version 1.4.7
the iptables release for the 2.6.33 kernel. Changes include:
- libipq is built as a shared library
- removal of some restrictions on interface names
- documentation updates
- code cleanups
See the changelog for more details.
Version 1.4.7 can be obtained from:
http://www.netfilter.org/projects/iptables/downloads.html
ftp://ftp.netfilter.org/pub/iptables/
git://git.netfilter.org/iptables.git
On behalf of the Netfilter Core Team.
Happy firewalling!
[-- Attachment #2: changes-iptables-1.4.7.txt --]
[-- Type: text/plain, Size: 552 bytes --]
Dmitry V. Levin (1):
libip4tc: Add static qualifier to dump_entry()
Jan Engelhardt (8):
libipq: build as shared library
recent: reorder cases in code (cosmetic cleanup)
doc: fix recent manpage to reflect actual supported syntax
doc: fix limit manpage to reflect actual supported syntax
doc: mention requirement of additional packages for ipset
policy: fix error message showing wrong option
includes: header updates
Lift restrictions on interface names
Patrick McHardy (1):
iptables 1.4.7
^ permalink raw reply
* Re: net: rtnetlink: support specifying device flags on device creation
From: Patrick McHardy @ 2010-03-01 15:24 UTC (permalink / raw)
To: David Miller; +Cc: netdev
In-Reply-To: <20100227.025128.186425822.davem@davemloft.net>
David Miller wrote:
> From: Patrick McHardy <kaber@trash.net>
> Date: Fri, 26 Feb 2010 17:34:49 +0100 (MET)
>
>> The following patches add support to specify the device flags (like UP) when
>> creating a new device through rtnl_link. This requires to surpress netlink
>> notifications until the device is fully configured in order to not confuse
>> userspace when changing the flags fails and registration has to be undone.
>> Once the device is configured, a single NEWLINK message with the full state
>> is sent.
>>
>> The individual patch changelogs describe the necessary changes in more detail.
>
> All applied, but two things:
>
> 1) This patch set was harder to review because there were no
> default initializations of the new enumeration you added
> to struct netdev.
>
> I know RTNL_LINK_INITIALIZED is probably zero by C enumeration
> rules, and the zeroing out of new netdev objects gives us this,
> but I only figured that out after some time.
>
> It deserved at least a commit message mention in patch #2.
Agreed. The reason to use the value 0 for RTNL_LINK_INITIALIZED
was that it avoids touching drivers that can register netdevices
through non rtnl_link paths, like bonding, ifb or dummy.
> 2) I would really appreciate you forming your patch postings
> properly. I have to edit them every single time
>
> You put the whole output of "git show" or "git format-patch" into
> your email body. That doesn't work, we don't want all of those
> commit ID etc. lines in there. It also causes every line of your
> commit messages to be indented by 4 spaces.
>
> Your email body should just contain the unindented commit message
> and the signoffs, then the patch itself.
>
> Your Subject lines are also not setup properly. Because the
> "net X/N:" thing isn't in [] brackets, it ends up in the
> commit message header lines when I feed your emails to
> "git am".
>
> All of this could be avoided if you used git send-email but
> I realize that a lot of people dislike that for one reason
> or another (myself included), but if you're going to compose
> the emails by hand you ought to make it look the same (syntax
> wise) as what git send-email would have emitted.
I'll either switch to git-send-email or make sure my script
works properly with git-am.
^ permalink raw reply
* call ((+2348056281072)) for your western union promo
From: WESTERNUNION PAY CENTER @ 2010-03-01 15:26 UTC (permalink / raw)
You have been awarded with the sum of $50,000 USD by our office, as one of our
customers who use Western Union in their daily business transaction.Please
provide Mr.Dominic Johnson with the following details listed below so that
your fund will be remited to you through Western Union.
1. Name:______
2. Address________
3. Country:_______
4. Phone Number____
5. Occupation:________
6. Sex:_________________
7. Age___________________
Mr.Dominic Johnson
Tel;+2348056281072
E-mail: w.unionclaim1@w.cn
^ permalink raw reply
* Re: [RFC PATCH]xfrm: fix perpetual bundles
From: Steffen Klassert @ 2010-03-01 15:33 UTC (permalink / raw)
To: jamal; +Cc: davem, kaber, herbert, yoshfuji, nakam, eric.dumazet, netdev
In-Reply-To: <1267366035.24915.24.camel@bigi>
Hi Jamal.
On Sun, Feb 28, 2010 at 09:07:15AM -0500, jamal wrote:
> Steffen,
>
> Did you try the simple patch i posted? After contemplating
> in the background i think it is the right thing to do.
> Ive also fixed IPV6 side the same way.
>
Yes, I did. Your patch works fine. As your solution is less
invasive we probaply should take your patches if nobody else
has an opinion on this.
Steffen
^ permalink raw reply
* Re: sparse checking prevented by "net: fix kmemcheck annotations"
From: Stefan Richter @ 2010-03-01 16:18 UTC (permalink / raw)
To: Eric Dumazet; +Cc: linux-kernel, David S. Miller, netdev
In-Reply-To: <1267448966.3039.22.camel@edumazet-laptop>
Eric Dumazet wrote:
> [PATCH] net: fix protocol sk_buff field
>
> Commit e992cd9b72a18 (kmemcheck: make bitfield annotations truly no-ops
> when disabled) allows us to revert a workaround we did in the past to
> not add holes in sk_buff structure.
>
> This patch partially reverts commit 14d18a81b5171
> (net: fix kmemcheck annotations) so that sparse doesnt complain:
>
> include/linux/skbuff.h:357:41: error: invalid bitfield specifier for
> type restricted __be16.
Great, very appreciated.
--
Stefan Richter
-=====-==-=- --== ----=
http://arcgraph.de/sr/
^ permalink raw reply
* Was: Re: [RFC PATCH] fix problems with NETIF_F_HIGHDMA in networking, Now: SWIOTLB dynamic allocation
From: Konrad Rzeszutek Wilk @ 2010-03-01 16:34 UTC (permalink / raw)
To: David Miller
Cc: fujita.tomonori, hancockrwd, bzolnier, linux-kernel, netdev,
linux-usb
In-Reply-To: <20100228.001628.48507956.davem@davemloft.net>
On Sun, Feb 28, 2010 at 12:16:28AM -0800, David Miller wrote:
> From: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
> Date: Sun, 28 Feb 2010 03:38:19 +0900
>
> > When I proposed such approach (always use swiotlb) before, IIRC,
> > the objections were:
> >
> > - better to make allocation respect dma_mask. (I don't think that this
> > approach is possible since we don't know which device handles data
> > later when we allocate memory).
>
> And such objects might end up being processed by multiple devices with
> different DMA restrictions.
>
> > - swiotlb is not good for small systems since it allocates too much
> > memory (we can fix this though).
>
> Indeed.
What would be a good mechanism for this? Enumerating all of the PCI
devices to find out which ones are 32-bit and then allocate some chunk
of memory based on the amount of them? say, 1MB per card?
Or maybe a simpler one - figure out how many pages we have an allocate
based on some sliding rule (say, 8MB for under 512MB, 16MB between 512MB
and 2GB, and 32MB for 2GB to 4GB, and after that the full 64MB?)
^ permalink raw reply
* [RFC] Setting processor affinity for network queues
From: Ben Hutchings @ 2010-03-01 17:21 UTC (permalink / raw)
To: netdev
Cc: Peter P Waskiewicz Jr, Peter Zijlstra, Thomas Gleixner,
Tom Herbert, Stephen Hemminger, sf-linux-drivers
With multiqueue network hardware or Receive/Transmit Packet Steering
(RPS/XPS) we can spread out network processing across multiple
processors. The administrator should be able to control the number of
channels and the processor affinity of each.
By 'channel' I mean a bundle of:
- a wakeup (IRQ or IPI)
- a receive queue whose completions trigger the wakeup
- a transmit queue whose completions trigger the wakeup
- a NAPI instance scheduled by the wakeup, which handles the completions
Numbers of RX and TX queues used on a device do not have to match, but
ideally they should. For generality, you can subsitute 'a receive
and/or a transmit queue' above. At the hardware level the numbers of
queues could be different e.g. in the sfc driver a channel would be
associated with 1 hardware RX queue, 2 hardware TX queues (with and
without checksum offload) and 1 hardware event queue.
Currently we have a userspace interface for setting affinity of IRQs and
a convention for naming each channel's IRQ handler, but no such
interface for memory allocation. For RX buffers this should not be a
problem since they are normally allocated as older buffers are
completed, in the NAPI context. However, the DMA descriptor rings and
driver structures for a channel should also be allocated on the NUMA
node where NAPI processing is done. Currently this allocation takes
place when a net device is created or when it is opened, before an
administrator has any opportunity to configure affinity. Reallocation
will normally require a complete stop to network traffic (at least on
the affected queues) so it should not be done automatically when the
driver detects a change in IRQ affinity. There needs to be an explicit
mechanism for changing it.
Devices using RPS will not generally be able to implement NUMA affinity
for RX buffer allocation, but there will be a similar issue of processor
selection for IPIs and NUMA node affinity for driver structures. The
proposed interface for setting processor affinity should cover this, but
it is completely different from the IRQ affinity mechanism for hardware
multiqueue devices. That seems undesirable.
Therefore I propose that:
1. Channels (or NAPI instances) should be exposed in sysfs.
2. Channels will have processor affinity, exposed read/write in sysfs.
Changing this triggers the networking core and driver to reallocate
associated structures if the processor affinity moved between NUMA
nodes, and triggers the driver to set IRQ affinity.
3. The networking core will set the initial affinity for each channel.
There may be global settings to control this.
4. Drivers should not set IRQ affinity.
5. irqbalanced should not set IRQ affinity for multiqueue network
devices.
(Most of this has been proposed already, but I'm trying to bring it all
together.)
Ben.
--
Ben Hutchings, Senior Software Engineer, Solarflare Communications
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
* RE: [RFC] Setting processor affinity for network queues
From: Tadepalli, Hari K @ 2010-03-01 17:43 UTC (permalink / raw)
To: Ben Hutchings, netdev
In-Reply-To: <1267464102.2092.136.camel@achroite.uk.solarflarecom.com>
>> From: netdev-owner@vger.kernel.org [mailto:netdev-owner@vger.kernel.org] On Behalf Of Ben Hutchings
>> Sent: Monday, March 01, 2010 10:22 AM
>> To: netdev
>> Cc: Waskiewicz Jr, Peter P; Peter Zijlstra; Thomas Gleixner; Tom Herbert; Stephen Hemminger; sf-linux-drivers
>> Subject: [RFC] Setting processor affinity for network queues
>>
>> Currently we have a userspace interface for setting affinity of IRQs and
>> a convention for naming each channel's IRQ handler, but no such
>> interface for memory allocation. For RX buffers this should not be a
>> problem since they are normally allocated as older buffers are
>> completed, in the NAPI context. However, the DMA descriptor rings and
>> driver structures for a channel should also be allocated on the NUMA
>> node where NAPI processing is done. Currently this allocation takes
>> place when a net device is created or when it is opened, before an
>> administrator has any opportunity to configure affinity. Reallocation
>> will normally require a complete stop to network traffic (at least on
>> the affected queues) so it should not be done automatically when the
>> driver detects a change in IRQ affinity
y. There needs to be an explicit
>> mechanism for changing it.
I have sought clarifications on this issue 2 weeks ago in the context of IxGbE:
http://marc.info/?l=linux-netdev&m=126638089307398&w=2
>> (i) tx_ring, rx_ring control structures of tx/rx rings:
>> tx_ring->tx_buffer_info = vmalloc_node(size, tx_ring->numa_node);
>>
>> (ii) descriptor rings in the DMA region: tx_ring->dma, rx_ring->dma
>> tx_ring->desc = pci_alloc_consistent(pdev, tx_ring->size, &tx_ring->dma);
>>
>> (iii) packet buffers:
>> struct sk_buff *skb = netdev_alloc_skb(adapter->netdev,bufsz);
The above memory allocation calls (sparing vmalloc_node()) conventionally used in a network driver allow for node awareness only at the physical device (pdev) level, where queues in a device do not have independent node-status. This is a serious setback to the benefits expected of recent developments for high throughput networking: RSS, 10/40GbE, NUMA & many cores on an SBC (single board computer or server). Cross node traffic, even in small proportions, is a retard on performance in the million packets/sec range.
I have hacked into some of the above, by using alloc_pages_node() & setting node_id explicitly when allocating for specific queues. But, look forward to a clean, 'hack-free' solution.
Thanks,
- Hari
__________________________________________
Embeedded Communications Group
Intel/ IAG, Chandler, AZ
^ permalink raw reply
* Re: [PATCH 1/1] bnx2x: Tx barriers and locks
From: Michael Chan @ 2010-03-01 17:59 UTC (permalink / raw)
To: Stanislaw Gruszka
Cc: Vladislav Zolotarov, netdev@vger.kernel.org, davem@davemloft.net,
Eilon Greenstein, Matthew Carlson
In-Reply-To: <20100301133339.GB2440@dhcp-lab-161.englab.brq.redhat.com>
On Mon, 2010-03-01 at 05:33 -0800, Stanislaw Gruszka wrote:
> On Sun, Feb 28, 2010 at 12:12:02PM +0200, Vladislav Zolotarov wrote:
> > --- a/drivers/net/bnx2x_main.c
> > +++ b/drivers/net/bnx2x_main.c
> > @@ -57,8 +57,8 @@
> > #include "bnx2x_init_ops.h"
> > #include "bnx2x_dump.h"
> >
> > -#define DRV_MODULE_VERSION "1.52.1-6"
> > -#define DRV_MODULE_RELDATE "2010/02/16"
> > +#define DRV_MODULE_VERSION "1.52.1-7"
> > +#define DRV_MODULE_RELDATE "2010/02/28"
> > #define BNX2X_BC_VER 0x040200
> >
> > #include <linux/firmware.h>
> > @@ -957,21 +957,34 @@ static int bnx2x_tx_int(struct bnx2x_fastpath *fp)
> > fp->tx_pkt_cons = sw_cons;
> > fp->tx_bd_cons = bd_cons;
> >
> > + /* Need to make the tx_bd_cons update visible to start_xmit()
> > + * before checking for netif_tx_queue_stopped(). Without the
> > + * memory barrier, there is a small possibility that
> > + * start_xmit() will miss it and cause the queue to be stopped
> > + * forever.
> > + */
> > + smp_wmb();
> > +
> > /* TBD need a thresh? */
> > if (unlikely(netif_tx_queue_stopped(txq))) {
> > -
> > - /* Need to make the tx_bd_cons update visible to start_xmit()
> > - * before checking for netif_tx_queue_stopped(). Without the
> > - * memory barrier, there is a small possibility that
> > - * start_xmit() will miss it and cause the queue to be stopped
> > - * forever.
> > + /* Taking tx_lock() is needed to prevent reenabling the queue
> > + * while it's empty. This could have happen if rx_action() gets
> > + * suspended in bnx2x_tx_int() after the condition before
> > + * netif_tx_wake_queue(), while tx_action (bnx2x_start_xmit()):
> > + *
> > + * stops the queue->sees fresh tx_bd_cons->releases the queue->
> > + * sends some packets consuming the whole queue again->
> > + * stops the queue
> > */
> > - smp_mb();
> > +
> > + __netif_tx_lock(txq, smp_processor_id());
> >
> > if ((netif_tx_queue_stopped(txq)) &&
> > (bp->state == BNX2X_STATE_OPEN) &&
> > (bnx2x_tx_avail(fp) >= MAX_SKB_FRAGS + 3))
> > netif_tx_wake_queue(txq);
> > +
> > + __netif_tx_unlock(txq);
> > }
> > return 0;
> > }
>
> There is still difference between what we have in bnx2x and bnx2/tg3
> regarding memory barriers in tx_poll/start_xmit code. Mainly we have
> smp_mb() in bnx2/tg3_tx_avail(), and in bnx2/tg3_tx_int() is smp_mb()
> not smp_wmb(). I do not see that bnx2x is wrong, but would like to know
> why there is a difference, maybe bnx2/tg3 should be changed?
>
The memory barrier in tx_int() is to make the tx index update happen
before the netif_tx_queue_stopped() check. The barrier is to prevent a
situation like this:
CPU0 CPU1
start_xmit()
if (tx_ring_full) {
tx_int()
if (!netif_tx_queue_stopped)
netif_tx_stop_queue()
if (!tx_ring_full)
update_tx_index
netif_tx_wake_queue()
}
The update_tx_index code is before the if statement in program order,
but the CPU and/or compiler can reorder it as shown above. smp_mb() will
prevent that. Will smp_wmb() prevent that as well?
^ permalink raw reply
* Re: [PATCH net-next-2.6] vhost: Restart tx poll when socket send queue is full
From: Shirley Ma @ 2010-02-26 3:09 UTC (permalink / raw)
To: Sridhar Samudrala; +Cc: Michael S. Tsirkin, David Miller, netdev
In-Reply-To: <1266946292.6364.6.camel@w-sridhar.beaverton.ibm.com>
This also fixes tx hung issue between guest and guest communication
through vhost.
Thanks
Shirley
^ permalink raw reply
* Re: [RFC][PATCH] ns: Syscalls for better namespace sharing control.
From: Eric W. Biederman @ 2010-03-01 19:24 UTC (permalink / raw)
To: Daniel Lezcano
Cc: Pavel Emelyanov, hadi, Patrick McHardy, Linux Netdev List,
containers, Netfilter Development Mailinglist, Ben Greear,
Serge Hallyn, Matt Helsley
In-Reply-To: <4B8AE8C1.1030305@free.fr>
Daniel Lezcano <daniel.lezcano@free.fr> writes:
>> Replacing struct pid is guaranteed to do all kinds of nasty things with
>> signal handling and the like, de_thread is nasty enough and you are talking
>> something worse. So if we can change pid namespaces without changing
>> the pid I am for it.
>
> I agree with all the points you and Pavel you talked about but I don't feel
> comfortable to have the current process to switch the pid namespace because of
> the process tree hierarchy (what will be the parent of the process when you
> enter the pid namespace for example). What is the difference with the sys_bindns
> or the sys_hijack, proposed a couple of years ago ?
I was not aiming at the general enter case. There is a very specific case
in networking where we only need a network namespace, not full blown containers
so I was seeing what could be done to handle the easy case.
The big idea is solving the namespace naming issues with bind mounts and file
descriptors. All of the rest is window dressing for that idea.
setns looks like the easy way but what is really needed for the network namespace
is a way to open sockets that are in a specified network namespace.
> I did a suggestion some weeks ago about a new syscall 'cloneat' where the child
> process becomes the child of the targeted process specified in the
> syscall. Maybe it would be interesting to replace the 'setns' by, or add, a
> cloneat' syscall with the file descriptor passed as parameter. The copy_process
> function shall not use the nsproxy of the caller but the one provided in the fd
> argument.
>
> The newly created process becomes the child of the process where we retrieve the
> namespace with nsfd and this one have to 'waitpid' it, (the caller of 'cloneat'
> can not wait it). It's a bit similar with the CLONE_PARENT flag, except the
> creation order is inverted (the father creates for the child).
>
> So when entering the container, we specify the pid 1 of the container which is
> usually a child reaper.
>
> Does it make sense ?
Essentially. I am not hugely interested in solving the general case
if it takes us off into tangents about pid namespace semantics.
I have just realized that while the original use case for having unix
domain sockets able to work across network namespaces was a little
weak, there are much better arguments. Operationally it is a game
changer. In the case where you don't need to support migration it
allows direct access to your X server and greatly simplifies the
design of a server designed to start processes in your container.
Eric
^ permalink raw reply
* [PATCH net-next-2.6] bridge: Fix build error when IGMP_SNOOPING is not enabled
From: Sridhar Samudrala @ 2010-03-01 19:53 UTC (permalink / raw)
To: Herbert Xu, David Miller; +Cc: netdev
Fix the following build error when IGMP_SNOOPING is not enabled.
In file included from net/bridge/br.c:24:
net/bridge/br_private.h: In function 'br_multicast_is_router':
net/bridge/br_private.h:361: error: 'struct net_bridge' has no member named 'multicast_router'
net/bridge/br_private.h:362: error: 'struct net_bridge' has no member named 'multicast_router'
net/bridge/br_private.h:363: error: 'struct net_bridge' has no member named 'multicast_router_timer'
Signed-off-by: Sridhar Samudrala <sri@us.ibm.com>
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 9191198..1cf2cef 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -302,6 +302,13 @@ extern int br_multicast_set_port_router(struct net_bridge_port *p,
unsigned long val);
extern int br_multicast_toggle(struct net_bridge *br, unsigned long val);
extern int br_multicast_set_hash_max(struct net_bridge *br, unsigned long val);
+
+static inline bool br_multicast_is_router(struct net_bridge *br)
+{
+ return br->multicast_router == 2 ||
+ (br->multicast_router == 1 &&
+ timer_pending(&br->multicast_router_timer));
+}
#else
static inline int br_multicast_rcv(struct net_bridge *br,
struct net_bridge_port *port,
@@ -354,14 +361,11 @@ static inline void br_multicast_forward(struct net_bridge_mdb_entry *mdst,
struct sk_buff *skb2)
{
}
-#endif
-
static inline bool br_multicast_is_router(struct net_bridge *br)
{
- return br->multicast_router == 2 ||
- (br->multicast_router == 1 &&
- timer_pending(&br->multicast_router_timer));
+ return 0;
}
+#endif
/* br_netfilter.c */
#ifdef CONFIG_BRIDGE_NETFILTER
^ permalink raw reply related
* HELLO
From: Rose Anderson @ 2010-03-01 20:23 UTC (permalink / raw)
HELLO
My name is Rose
i interested in you,i will also like to know you the more,and i want you to send an email to my email address so i can give you my picture for you to know whom i am Here is my email address (Rose_8v8@yahoo.com) i believe we can move from here!I am waiting for your mail to my email address above. Rose
(Remember the distance or color an age does not matter but love matters a lot in life
(Rose_8v8@yahoo.com)
^ permalink raw reply
* [PATCH] sis190: fix cable detect via link status poll
From: Jeff Garzik @ 2010-03-01 20:40 UTC (permalink / raw)
To: netdev
Some sis190 devices don't report LinkChange, so do polling for
link status.
Fixes http://bugzilla.kernel.org/show_bug.cgi?id=11926
Signed-off-by: Herton Ronaldo Krzesinski <herton@mandriva.com.br>
---
Alan Cox found this change languishing in bugzilla -- a problem with a
patch verified to fix the problem.
I updated the patch to apply to the most recent net-next kernel, but
have not received confirmation that my updated patch still fixes the
problem. -jgarzik
drivers/net/sis190.c | 23 ++++++++++++++++++-----
1 file changed, 18 insertions(+), 5 deletions(-)
diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c
index 80af4a4..760d9e8 100644
--- a/drivers/net/sis190.c
+++ b/drivers/net/sis190.c
@@ -285,6 +285,11 @@ struct sis190_private {
struct list_head first_phy;
u32 features;
u32 negotiated_lpa;
+ enum {
+ LNK_OFF,
+ LNK_ON,
+ LNK_AUTONEG,
+ } link_status;
};
struct sis190_phy {
@@ -750,6 +755,7 @@ static irqreturn_t sis190_interrupt(int irq, void *__dev)
if (status & LinkChange) {
netif_info(tp, intr, dev, "link change\n");
+ del_timer(&tp->timer);
schedule_work(&tp->phy_task);
}
@@ -922,12 +928,15 @@ static void sis190_phy_task(struct work_struct *work)
if (val & BMCR_RESET) {
// FIXME: needlessly high ? -- FR 02/07/2005
mod_timer(&tp->timer, jiffies + HZ/10);
- } else if (!(mdio_read_latched(ioaddr, phy_id, MII_BMSR) &
- BMSR_ANEGCOMPLETE)) {
+ goto out_unlock;
+ }
+
+ val = mdio_read_latched(ioaddr, phy_id, MII_BMSR);
+ if (!(val & BMSR_ANEGCOMPLETE) && tp->link_status != LNK_AUTONEG) {
netif_carrier_off(dev);
netif_warn(tp, link, dev, "auto-negotiating...\n");
- mod_timer(&tp->timer, jiffies + SIS190_PHY_TIMEOUT);
- } else {
+ tp->link_status = LNK_AUTONEG;
+ } else if ((val & BMSR_LSTATUS) && tp->link_status != LNK_ON) {
/* Rejoice ! */
struct {
int val;
@@ -1000,7 +1009,10 @@ static void sis190_phy_task(struct work_struct *work)
netif_info(tp, link, dev, "link on %s mode\n", p->msg);
netif_carrier_on(dev);
- }
+ tp->link_status = LNK_ON;
+ } else if (!(val & BMSR_LSTATUS) && tp->link_status != LNK_AUTONEG)
+ tp->link_status = LNK_OFF;
+ mod_timer(&tp->timer, jiffies + SIS190_PHY_TIMEOUT);
out_unlock:
rtnl_unlock();
@@ -1513,6 +1525,7 @@ static struct net_device * __devinit sis190_init_board(struct pci_dev *pdev)
tp->pci_dev = pdev;
tp->mmio_addr = ioaddr;
+ tp->link_status = LNK_OFF;
sis190_irq_mask_and_ack(ioaddr);
^ permalink raw reply related
* Re: [RFC] Setting processor affinity for network queues
From: Tom Herbert @ 2010-03-01 20:46 UTC (permalink / raw)
To: Ben Hutchings
Cc: netdev, Peter P Waskiewicz Jr, Peter Zijlstra, Thomas Gleixner,
Stephen Hemminger, sf-linux-drivers
In-Reply-To: <1267464102.2092.136.camel@achroite.uk.solarflarecom.com>
On Mon, Mar 1, 2010 at 9:21 AM, Ben Hutchings <bhutchings@solarflare.com> wrote:
> With multiqueue network hardware or Receive/Transmit Packet Steering
> (RPS/XPS) we can spread out network processing across multiple
> processors. The administrator should be able to control the number of
> channels and the processor affinity of each.
>
> By 'channel' I mean a bundle of:
> - a wakeup (IRQ or IPI)
> - a receive queue whose completions trigger the wakeup
> - a transmit queue whose completions trigger the wakeup
> - a NAPI instance scheduled by the wakeup, which handles the completions
>
Yes. Also in the receive side it is really cumbersome to do per NAPI
RPS settings without the receive napi instance not be exposed in
netif_rx. Maybe a reference to NAPI structure can be added in skb?
This could clean up RPS a lot.
Tom
> Numbers of RX and TX queues used on a device do not have to match, but
> ideally they should. For generality, you can subsitute 'a receive
> and/or a transmit queue' above. At the hardware level the numbers of
> queues could be different e.g. in the sfc driver a channel would be
> associated with 1 hardware RX queue, 2 hardware TX queues (with and
> without checksum offload) and 1 hardware event queue.
>
> Currently we have a userspace interface for setting affinity of IRQs and
> a convention for naming each channel's IRQ handler, but no such
> interface for memory allocation. For RX buffers this should not be a
> problem since they are normally allocated as older buffers are
> completed, in the NAPI context. However, the DMA descriptor rings and
> driver structures for a channel should also be allocated on the NUMA
> node where NAPI processing is done. Currently this allocation takes
> place when a net device is created or when it is opened, before an
> administrator has any opportunity to configure affinity. Reallocation
> will normally require a complete stop to network traffic (at least on
> the affected queues) so it should not be done automatically when the
> driver detects a change in IRQ affinity. There needs to be an explicit
> mechanism for changing it.
>
> Devices using RPS will not generally be able to implement NUMA affinity
> for RX buffer allocation, but there will be a similar issue of processor
> selection for IPIs and NUMA node affinity for driver structures. The
> proposed interface for setting processor affinity should cover this, but
> it is completely different from the IRQ affinity mechanism for hardware
> multiqueue devices. That seems undesirable.
>
> Therefore I propose that:
>
> 1. Channels (or NAPI instances) should be exposed in sysfs.
> 2. Channels will have processor affinity, exposed read/write in sysfs.
> Changing this triggers the networking core and driver to reallocate
> associated structures if the processor affinity moved between NUMA
> nodes, and triggers the driver to set IRQ affinity.
> 3. The networking core will set the initial affinity for each channel.
> There may be global settings to control this.
> 4. Drivers should not set IRQ affinity.
> 5. irqbalanced should not set IRQ affinity for multiqueue network
> devices.
>
> (Most of this has been proposed already, but I'm trying to bring it all
> together.)
>
> Ben.
>
> --
> Ben Hutchings, Senior Software Engineer, Solarflare Communications
> 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
* Re: [PATCH net-next-2.6] bridge: Fix build error when IGMP_SNOOPING is not enabled
From: Randy Dunlap @ 2010-03-01 20:54 UTC (permalink / raw)
To: Sridhar Samudrala; +Cc: Herbert Xu, David Miller, netdev
In-Reply-To: <1267473184.31728.7.camel@w-sridhar.beaverton.ibm.com>
On 03/01/10 11:53, Sridhar Samudrala wrote:
> Fix the following build error when IGMP_SNOOPING is not enabled.
> In file included from net/bridge/br.c:24:
> net/bridge/br_private.h: In function 'br_multicast_is_router':
> net/bridge/br_private.h:361: error: 'struct net_bridge' has no member named 'multicast_router'
> net/bridge/br_private.h:362: error: 'struct net_bridge' has no member named 'multicast_router'
> net/bridge/br_private.h:363: error: 'struct net_bridge' has no member named 'multicast_router_timer'
>
> Signed-off-by: Sridhar Samudrala <sri@us.ibm.com>
>
> diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
> index 9191198..1cf2cef 100644
> --- a/net/bridge/br_private.h
> +++ b/net/bridge/br_private.h
> @@ -302,6 +302,13 @@ extern int br_multicast_set_port_router(struct net_bridge_port *p,
> unsigned long val);
> extern int br_multicast_toggle(struct net_bridge *br, unsigned long val);
> extern int br_multicast_set_hash_max(struct net_bridge *br, unsigned long val);
> +
> +static inline bool br_multicast_is_router(struct net_bridge *br)
> +{
> + return br->multicast_router == 2 ||
> + (br->multicast_router == 1 &&
> + timer_pending(&br->multicast_router_timer));
> +}
> #else
> static inline int br_multicast_rcv(struct net_bridge *br,
> struct net_bridge_port *port,
> @@ -354,14 +361,11 @@ static inline void br_multicast_forward(struct net_bridge_mdb_entry *mdst,
> struct sk_buff *skb2)
> {
> }
> -#endif
> -
> static inline bool br_multicast_is_router(struct net_bridge *br)
> {
> - return br->multicast_router == 2 ||
> - (br->multicast_router == 1 &&
> - timer_pending(&br->multicast_router_timer));
> + return 0;
> }
> +#endif
>
> /* br_netfilter.c */
> #ifdef CONFIG_BRIDGE_NETFILTER
>
>
> --
Acked-by: Randy Dunlap <randy.dunlap@oracle.com>
Thanks.
--
~Randy
^ 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