* [PATCH net-next-2.6] be2net: Changes to use only priority codes allowed by f/w
From: Somnath Kotur @ 2010-10-19 8:51 UTC (permalink / raw)
To: netdev
Changes to use one of the priority codes allowed by CNA f/w for NIC traffic
from host. The driver gets the bit map of the priority codes allowed for
host traffic through a asynchronous message from the f/w that the driver
subscribes to.
Signed-off-by: Somnath Kotur <somnath.kotur@emulex.com>
---
drivers/net/benet/be.h | 2 +
drivers/net/benet/be_cmds.c | 60 +++++++++++++++++++++++++++++++++++++++++-
drivers/net/benet/be_cmds.h | 31 ++++++++++++++++++++++
drivers/net/benet/be_main.c | 21 ++++++++++-----
4 files changed, 105 insertions(+), 9 deletions(-)
diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h
index 1afabb1..7ff66fb 100644
--- a/drivers/net/benet/be.h
+++ b/drivers/net/benet/be.h
@@ -264,6 +264,8 @@ struct be_adapter {
u16 vlans_added;
u16 max_vlans; /* Number of vlans supported */
u8 vlan_tag[VLAN_GROUP_ARRAY_LEN];
+ u8 vlan_prio_bmap; /* Available priority BitMap */
+ u16 recommended_prio; /* Recommended Priority */
struct be_dma_mem mc_cmd_mem;
struct be_dma_mem stats_cmd;
diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c
index bf2dc26..b1728db 100644
--- a/drivers/net/benet/be_cmds.c
+++ b/drivers/net/benet/be_cmds.c
@@ -96,6 +96,50 @@ static void be_async_link_state_process(struct be_adapter *adapter,
evt->port_link_status == ASYNC_EVENT_LINK_UP);
}
+/* Grp5 CoS Priority evt */
+static void be_async_grp5_cos_priority_process(struct be_adapter *adapter,
+ struct be_async_event_grp5_cos_priority *evt)
+{
+ if (evt->valid) {
+ adapter->vlan_prio_bmap = evt->available_priority_bmap;
+ adapter->recommended_prio =
+ evt->reco_default_priority << VLAN_PRIO_SHIFT;
+ }
+}
+
+/* Grp5 QOS Speed evt */
+static void be_async_grp5_qos_speed_process(struct be_adapter *adapter,
+ struct be_async_event_grp5_qos_link_speed *evt)
+{
+ if (evt->physical_port == adapter->port_num) {
+ /* qos_link_speed is in units of 10 Mbps */
+ adapter->link_speed = evt->qos_link_speed * 10;
+ }
+}
+
+static void be_async_grp5_evt_process(struct be_adapter *adapter,
+ u32 trailer, struct be_mcc_compl *evt)
+{
+ u8 event_type = 0;
+
+ event_type = (trailer >> ASYNC_TRAILER_EVENT_TYPE_SHIFT) &
+ ASYNC_TRAILER_EVENT_TYPE_MASK;
+
+ switch (event_type) {
+ case ASYNC_EVENT_COS_PRIORITY:
+ be_async_grp5_cos_priority_process(adapter,
+ (struct be_async_event_grp5_cos_priority *)evt);
+ break;
+ case ASYNC_EVENT_QOS_SPEED:
+ be_async_grp5_qos_speed_process(adapter,
+ (struct be_async_event_grp5_qos_link_speed *)evt);
+ break;
+ default:
+ dev_warn(&adapter->pdev->dev, "Unknown grp5 event!\n");
+ break;
+ }
+}
+
static inline bool is_link_state_evt(u32 trailer)
{
return ((trailer >> ASYNC_TRAILER_EVENT_CODE_SHIFT) &
@@ -103,6 +147,13 @@ static inline bool is_link_state_evt(u32 trailer)
ASYNC_EVENT_CODE_LINK_STATE;
}
+static inline bool is_grp5_evt(u32 trailer)
+{
+ return (((trailer >> ASYNC_TRAILER_EVENT_CODE_SHIFT) &
+ ASYNC_TRAILER_EVENT_CODE_MASK) ==
+ ASYNC_EVENT_CODE_GRP_5);
+}
+
static struct be_mcc_compl *be_mcc_compl_get(struct be_adapter *adapter)
{
struct be_queue_info *mcc_cq = &adapter->mcc_obj.cq;
@@ -143,6 +194,9 @@ int be_process_mcc(struct be_adapter *adapter, int *status)
if (is_link_state_evt(compl->flags))
be_async_link_state_process(adapter,
(struct be_async_event_link_state *) compl);
+ else if (is_grp5_evt(compl->flags))
+ be_async_grp5_evt_process(adapter,
+ compl->flags, compl);
} else if (compl->flags & CQE_FLAGS_COMPLETED_MASK) {
*status = be_mcc_compl_process(adapter, compl);
atomic_dec(&mcc_obj->q.used);
@@ -677,10 +731,10 @@ int be_cmd_mccq_create(struct be_adapter *adapter,
ctxt = &req->context;
be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0,
- OPCODE_COMMON_MCC_CREATE);
+ OPCODE_COMMON_MCC_CREATE_EXT);
be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
- OPCODE_COMMON_MCC_CREATE, sizeof(*req));
+ OPCODE_COMMON_MCC_CREATE_EXT, sizeof(*req));
req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size));
@@ -688,6 +742,8 @@ int be_cmd_mccq_create(struct be_adapter *adapter,
AMAP_SET_BITS(struct amap_mcc_context, ring_size, ctxt,
be_encoded_q_len(mccq->len));
AMAP_SET_BITS(struct amap_mcc_context, cq_id, ctxt, cq->id);
+ /* Subscribe to Link State and Group 5 Events(bits 1 and 5 set) */
+ req->async_event_bitmap[0] |= 0x00000022;
be_dws_cpu_to_le(ctxt, sizeof(req->context));
diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h
index b7a40b1..93c721a 100644
--- a/drivers/net/benet/be_cmds.h
+++ b/drivers/net/benet/be_cmds.h
@@ -82,7 +82,12 @@ struct be_mcc_compl {
*/
#define ASYNC_TRAILER_EVENT_CODE_SHIFT 8 /* bits 8 - 15 */
#define ASYNC_TRAILER_EVENT_CODE_MASK 0xFF
+#define ASYNC_TRAILER_EVENT_TYPE_SHIFT 16 /* bits 16 - 23 */
+#define ASYNC_TRAILER_EVENT_TYPE_MASK 0xFF
#define ASYNC_EVENT_CODE_LINK_STATE 0x1
+#define ASYNC_EVENT_CODE_GRP_5 0x5
+#define ASYNC_EVENT_QOS_SPEED 0x1
+#define ASYNC_EVENT_COS_PRIORITY 0x2
struct be_async_event_trailer {
u32 code;
};
@@ -105,6 +110,30 @@ struct be_async_event_link_state {
struct be_async_event_trailer trailer;
} __packed;
+/* When the event code of an async trailer is GRP-5 and event_type is QOS_SPEED
+ * the mcc_compl must be interpreted as follows
+ */
+struct be_async_event_grp5_qos_link_speed {
+ u8 physical_port;
+ u8 rsvd[5];
+ u16 qos_link_speed;
+ u32 event_tag;
+ struct be_async_event_trailer trailer;
+} __packed;
+
+/* When the event code of an async trailer is GRP5 and event type is
+ * CoS-Priority, the mcc_compl must be interpreted as follows
+ */
+struct be_async_event_grp5_cos_priority {
+ u8 physical_port;
+ u8 available_priority_bmap;
+ u8 reco_default_priority;
+ u8 valid;
+ u8 rsvd0;
+ u8 event_tag;
+ struct be_async_event_trailer trailer;
+} __packed;
+
struct be_mcc_mailbox {
struct be_mcc_wrb wrb;
struct be_mcc_compl compl;
@@ -125,6 +154,7 @@ struct be_mcc_mailbox {
#define OPCODE_COMMON_EQ_CREATE 13
#define OPCODE_COMMON_MCC_CREATE 21
#define OPCODE_COMMON_SET_QOS 28
+#define OPCODE_COMMON_MCC_CREATE_EXT 90
#define OPCODE_COMMON_SEEPROM_READ 30
#define OPCODE_COMMON_NTWK_RX_FILTER 34
#define OPCODE_COMMON_GET_FW_VERSION 35
@@ -338,6 +368,7 @@ struct be_cmd_req_mcc_create {
struct be_cmd_req_hdr hdr;
u16 num_pages;
u16 rsvd0;
+ u32 async_event_bitmap[1];
u8 context[sizeof(struct amap_mcc_context) / 8];
struct phys_addr pages[8];
} __packed;
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c
index 9a1cd28..5374be1 100644
--- a/drivers/net/benet/be_main.c
+++ b/drivers/net/benet/be_main.c
@@ -429,9 +429,12 @@ static inline void wrb_fill(struct be_eth_wrb *wrb, u64 addr, int len)
wrb->frag_len = len & ETH_WRB_FRAG_LEN_MASK;
}
-static void wrb_fill_hdr(struct be_eth_hdr_wrb *hdr, struct sk_buff *skb,
- bool vlan, u32 wrb_cnt, u32 len)
+static void wrb_fill_hdr(struct be_adapter *adapter, struct be_eth_hdr_wrb *hdr,
+ struct sk_buff *skb, u32 wrb_cnt, u32 len)
{
+ u8 vlan_prio = 0;
+ u16 vlan_tag = 0;
+
memset(hdr, 0, sizeof(*hdr));
AMAP_SET_BITS(struct amap_eth_hdr_wrb, crc, hdr, 1);
@@ -449,10 +452,15 @@ static void wrb_fill_hdr(struct be_eth_hdr_wrb *hdr, struct sk_buff *skb,
AMAP_SET_BITS(struct amap_eth_hdr_wrb, udpcs, hdr, 1);
}
- if (vlan && vlan_tx_tag_present(skb)) {
+ if (adapter->vlan_grp && vlan_tx_tag_present(skb)) {
AMAP_SET_BITS(struct amap_eth_hdr_wrb, vlan, hdr, 1);
- AMAP_SET_BITS(struct amap_eth_hdr_wrb, vlan_tag,
- hdr, vlan_tx_tag_get(skb));
+ vlan_tag = vlan_tx_tag_get(skb);
+ vlan_prio = (vlan_tag & VLAN_PRIO_MASK) >> VLAN_PRIO_SHIFT;
+ /* If vlan priority provided by OS is NOT in available bmap */
+ if (!(adapter->vlan_prio_bmap & (1 << vlan_prio)))
+ vlan_tag = (vlan_tag & ~VLAN_PRIO_MASK) |
+ adapter->recommended_prio;
+ AMAP_SET_BITS(struct amap_eth_hdr_wrb, vlan_tag, hdr, vlan_tag);
}
AMAP_SET_BITS(struct amap_eth_hdr_wrb, event, hdr, 1);
@@ -532,8 +540,7 @@ static int make_tx_wrbs(struct be_adapter *adapter,
queue_head_inc(txq);
}
- wrb_fill_hdr(hdr, first_skb, adapter->vlan_grp ? true : false,
- wrb_cnt, copied);
+ wrb_fill_hdr(adapter, hdr, first_skb, wrb_cnt, copied);
be_dws_cpu_to_le(hdr, sizeof(*hdr));
return copied;
--
1.5.6.1
^ permalink raw reply related
* [RFC net-next] caif: code cleanup
From: Stephen Hemminger @ 2010-10-19 16:55 UTC (permalink / raw)
To: Sjur Braendeland; +Cc: netdev
Cleanup of new CAIF code.
* make local functions static
* remove code that is never used
* expand get_caif_conf() since wrapper is no longer needed
* make args to comparison functions const
* rename connect_req_to_link_param to keep exported names
consistent
Compile tested only.
Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
---
include/net/caif/caif_dev.h | 27 +-----
include/net/caif/cfctrl.h | 12 --
include/net/caif/cfmuxl.h | 2
include/net/caif/cfpkt.h | 75 ------------------
include/net/caif/cfsrvl.h | 3
net/caif/caif_config_util.c | 6 -
net/caif/caif_dev.c | 24 +----
net/caif/cfcnfg.c | 2
net/caif/cfctrl.c | 74 +-----------------
net/caif/cfmuxl.c | 35 --------
net/caif/cfpkt_skbuff.c | 178 +-------------------------------------------
net/caif/cfsrvl.c | 7 -
12 files changed, 29 insertions(+), 416 deletions(-)
--- a/include/net/caif/caif_dev.h 2010-10-19 09:25:53.581751379 -0700
+++ b/include/net/caif/caif_dev.h 2010-10-19 09:53:00.077792212 -0700
@@ -74,19 +74,8 @@ int caif_connect_client(struct caif_conn
int caif_disconnect_client(struct cflayer *client_layer);
/**
- * caif_release_client - Release adaptation layer reference to client.
- *
- * @client_layer: Client layer.
- *
- * Releases a client/adaptation layer use of the caif stack.
- * This function must be used after caif_disconnect_client to
- * decrease the reference count of the service layer.
- */
-void caif_release_client(struct cflayer *client_layer);
-
-/**
- * connect_req_to_link_param - Translate configuration parameters
- * from socket format to internal format.
+ * caif_connect_req_to_link_param - Translate configuration parameters
+ * from socket format to internal format.
* @cnfg: Pointer to configuration handler
* @con_req: Configuration parameters supplied in function
* caif_connect_client
@@ -94,14 +83,8 @@ void caif_release_client(struct cflayer
* setting up channels.
*
*/
-int connect_req_to_link_param(struct cfcnfg *cnfg,
- struct caif_connect_request *con_req,
- struct cfctrl_link_param *channel_setup_param);
-
-/**
- * get_caif_conf() - Get the configuration handler.
- */
-struct cfcnfg *get_caif_conf(void);
-
+int caif_connect_req_to_link_param(struct cfcnfg *cnfg,
+ struct caif_connect_request *con_req,
+ struct cfctrl_link_param *channel_setup_param);
#endif /* CAIF_DEV_H_ */
--- a/include/net/caif/cfctrl.h 2010-10-19 09:25:53.709764168 -0700
+++ b/include/net/caif/cfctrl.h 2010-10-19 09:39:11.361244959 -0700
@@ -121,19 +121,9 @@ int cfctrl_linkup_request(struct cflayer
struct cflayer *user_layer);
int cfctrl_linkdown_req(struct cflayer *cfctrl, u8 linkid,
struct cflayer *client);
-void cfctrl_sleep_req(struct cflayer *cfctrl);
-void cfctrl_wake_req(struct cflayer *cfctrl);
-void cfctrl_getstartreason_req(struct cflayer *cfctrl);
+
struct cflayer *cfctrl_create(void);
-void cfctrl_set_dnlayer(struct cflayer *this, struct cflayer *dn);
-void cfctrl_set_uplayer(struct cflayer *this, struct cflayer *up);
struct cfctrl_rsp *cfctrl_get_respfuncs(struct cflayer *layer);
-bool cfctrl_req_eq(struct cfctrl_request_info *r1,
- struct cfctrl_request_info *r2);
-void cfctrl_insert_req(struct cfctrl *ctrl,
- struct cfctrl_request_info *req);
-struct cfctrl_request_info *cfctrl_remove_req(struct cfctrl *ctrl,
- struct cfctrl_request_info *req);
void cfctrl_cancel_req(struct cflayer *layr, struct cflayer *adap_layer);
#endif /* CFCTRL_H_ */
--- a/include/net/caif/cfpkt.h 2010-10-19 09:25:53.785771759 -0700
+++ b/include/net/caif/cfpkt.h 2010-10-19 09:37:32.651429118 -0700
@@ -16,12 +16,6 @@ struct cfpkt;
*/
struct cfpkt *cfpkt_create(u16 len);
-/* Create a CAIF packet.
- * data Data to copy.
- * len Length of packet to be created
- * @return New packet.
- */
-struct cfpkt *cfpkt_create_uplink(const unsigned char *data, unsigned int len);
/*
* Destroy a CAIF Packet.
* pkt Packet to be destoyed.
@@ -181,22 +175,6 @@ u16 cfpkt_iterate(struct cfpkt *pkt,
u16 (*iter_func)(u16 chks, void *buf, u16 len),
u16 data);
-/* Append by giving user access to packet buffer
- * cfpkt Packet to append to
- * buf Buffer inside pkt that user shall copy data into
- * buflen Length of buffer and number of bytes added to packet
- * @return 0 on error, 1 on success
- */
-int cfpkt_raw_append(struct cfpkt *cfpkt, void **buf, unsigned int buflen);
-
-/* Extract by giving user access to packet buffer
- * cfpkt Packet to extract from
- * buf Buffer inside pkt that user shall copy data from
- * buflen Length of buffer and number of bytes removed from packet
- * @return 0 on error, 1 on success
- */
-int cfpkt_raw_extract(struct cfpkt *cfpkt, void **buf, unsigned int buflen);
-
/* Map from a "native" packet (e.g. Linux Socket Buffer) to a CAIF packet.
* dir - Direction indicating whether this packet is to be sent or received.
* nativepkt - The native packet to be transformed to a CAIF packet
@@ -210,59 +188,6 @@ struct cfpkt *cfpkt_fromnative(enum caif
*/
void *cfpkt_tonative(struct cfpkt *pkt);
-/*
- * Insert a packet in the packet queue.
- * pktq Packet queue to insert into
- * pkt Packet to be inserted in queue
- * prio Priority of packet
- */
-void cfpkt_queue(struct cfpktq *pktq, struct cfpkt *pkt,
- unsigned short prio);
-
-/*
- * Remove a packet from the packet queue.
- * pktq Packet queue to fetch packets from.
- * @return Dequeued packet.
- */
-struct cfpkt *cfpkt_dequeue(struct cfpktq *pktq);
-
-/*
- * Peek into a packet from the packet queue.
- * pktq Packet queue to fetch packets from.
- * @return Peeked packet.
- */
-struct cfpkt *cfpkt_qpeek(struct cfpktq *pktq);
-
-/*
- * Initiates the packet queue.
- * @return Pointer to new packet queue.
- */
-struct cfpktq *cfpktq_create(void);
-
-/*
- * Get the number of packets in the queue.
- * pktq Packet queue to fetch count from.
- * @return Number of packets in queue.
- */
-int cfpkt_qcount(struct cfpktq *pktq);
-
-/*
- * Put content of packet into buffer for debuging purposes.
- * pkt Packet to copy data from
- * buf Buffer to copy data into
- * buflen Length of data to copy
- * @return Pointer to copied data
- */
-char *cfpkt_log_pkt(struct cfpkt *pkt, char *buf, int buflen);
-
-/*
- * Clones a packet and releases the original packet.
- * This is used for taking ownership of a packet e.g queueing.
- * pkt Packet to clone and release.
- * @return Cloned packet.
- */
-struct cfpkt *cfpkt_clone_release(struct cfpkt *pkt);
-
/*
* Returns packet information for a packet.
--- a/net/caif/caif_dev.c 2010-10-19 09:26:08.959287331 -0700
+++ b/net/caif/caif_dev.c 2010-10-19 09:53:28.508446823 -0700
@@ -257,7 +257,7 @@ static int caif_device_notify(struct not
break;
}
dev_hold(dev);
- cfcnfg_add_phy_layer(get_caif_conf(),
+ cfcnfg_add_phy_layer(cfg,
phy_type,
dev,
&caifd->layer,
@@ -300,7 +300,7 @@ static int caif_device_notify(struct not
if (atomic_read(&caifd->in_use))
netdev_warn(dev,
"Unregistering an active CAIF device\n");
- cfcnfg_del_phy_layer(get_caif_conf(), &caifd->layer);
+ cfcnfg_del_phy_layer(cfg, &caifd->layer);
dev_put(dev);
atomic_set(&caifd->state, what);
break;
@@ -320,24 +320,18 @@ static struct notifier_block caif_device
.priority = 0,
};
-
-struct cfcnfg *get_caif_conf(void)
-{
- return cfg;
-}
-EXPORT_SYMBOL(get_caif_conf);
-
int caif_connect_client(struct caif_connect_request *conn_req,
struct cflayer *client_layer, int *ifindex,
int *headroom, int *tailroom)
{
struct cfctrl_link_param param;
int ret;
- ret = connect_req_to_link_param(get_caif_conf(), conn_req, ¶m);
+
+ ret = caif_connect_req_to_link_param(cfg, conn_req, ¶m);
if (ret)
return ret;
/* Hook up the adaptation layer. */
- return cfcnfg_add_adaptation_layer(get_caif_conf(), ¶m,
+ return cfcnfg_add_adaptation_layer(cfg, ¶m,
client_layer, ifindex,
headroom, tailroom);
}
@@ -345,16 +339,10 @@ EXPORT_SYMBOL(caif_connect_client);
int caif_disconnect_client(struct cflayer *adap_layer)
{
- return cfcnfg_disconn_adapt_layer(get_caif_conf(), adap_layer);
+ return cfcnfg_disconn_adapt_layer(cfg, adap_layer);
}
EXPORT_SYMBOL(caif_disconnect_client);
-void caif_release_client(struct cflayer *adap_layer)
-{
- cfcnfg_release_adap_layer(adap_layer);
-}
-EXPORT_SYMBOL(caif_release_client);
-
/* Per-namespace Caif devices handling */
static int caif_init_net(struct net *net)
{
--- a/net/caif/cfcnfg.c 2010-10-19 09:24:41.354535051 -0700
+++ b/net/caif/cfcnfg.c 2010-10-19 09:25:17.390135851 -0700
@@ -257,7 +257,7 @@ static void cfcnfg_linkdestroy_rsp(struc
{
}
-int protohead[CFCTRL_SRV_MASK] = {
+static const int protohead[CFCTRL_SRV_MASK] = {
[CFCTRL_SRV_VEI] = 4,
[CFCTRL_SRV_DATAGRAM] = 7,
[CFCTRL_SRV_UTIL] = 4,
--- a/net/caif/cfctrl.c 2010-10-19 09:29:11.169475442 -0700
+++ b/net/caif/cfctrl.c 2010-10-19 09:40:24.472511862 -0700
@@ -58,7 +58,7 @@ struct cflayer *cfctrl_create(void)
return &this->serv.layer;
}
-static bool param_eq(struct cfctrl_link_param *p1, struct cfctrl_link_param *p2)
+static bool param_eq(const struct cfctrl_link_param *p1, const struct cfctrl_link_param *p2)
{
bool eq =
p1->linktype == p2->linktype &&
@@ -100,8 +100,8 @@ static bool param_eq(struct cfctrl_link_
return false;
}
-bool cfctrl_req_eq(struct cfctrl_request_info *r1,
- struct cfctrl_request_info *r2)
+static bool cfctrl_req_eq(const struct cfctrl_request_info *r1,
+ const struct cfctrl_request_info *r2)
{
if (r1->cmd != r2->cmd)
return false;
@@ -112,7 +112,7 @@ bool cfctrl_req_eq(struct cfctrl_request
}
/* Insert request at the end */
-void cfctrl_insert_req(struct cfctrl *ctrl,
+static void cfctrl_insert_req(struct cfctrl *ctrl,
struct cfctrl_request_info *req)
{
spin_lock(&ctrl->info_list_lock);
@@ -123,8 +123,8 @@ void cfctrl_insert_req(struct cfctrl *ct
}
/* Compare and remove request */
-struct cfctrl_request_info *cfctrl_remove_req(struct cfctrl *ctrl,
- struct cfctrl_request_info *req)
+static struct cfctrl_request_info *cfctrl_remove_req(struct cfctrl *ctrl,
+ struct cfctrl_request_info *req)
{
struct cfctrl_request_info *p, *tmp, *first;
@@ -154,16 +154,6 @@ struct cfctrl_rsp *cfctrl_get_respfuncs(
return &this->res;
}
-void cfctrl_set_dnlayer(struct cflayer *this, struct cflayer *dn)
-{
- this->dn = dn;
-}
-
-void cfctrl_set_uplayer(struct cflayer *this, struct cflayer *up)
-{
- this->up = up;
-}
-
static void init_info(struct caif_payload_info *info, struct cfctrl *cfctrl)
{
info->hdr_len = 0;
@@ -304,58 +294,6 @@ int cfctrl_linkdown_req(struct cflayer *
return ret;
}
-void cfctrl_sleep_req(struct cflayer *layer)
-{
- int ret;
- struct cfctrl *cfctrl = container_obj(layer);
- struct cfpkt *pkt = cfpkt_create(CFPKT_CTRL_PKT_LEN);
- if (!pkt) {
- pr_warn("Out of memory\n");
- return;
- }
- cfpkt_addbdy(pkt, CFCTRL_CMD_SLEEP);
- init_info(cfpkt_info(pkt), cfctrl);
- ret =
- cfctrl->serv.layer.dn->transmit(cfctrl->serv.layer.dn, pkt);
- if (ret < 0)
- cfpkt_destroy(pkt);
-}
-
-void cfctrl_wake_req(struct cflayer *layer)
-{
- int ret;
- struct cfctrl *cfctrl = container_obj(layer);
- struct cfpkt *pkt = cfpkt_create(CFPKT_CTRL_PKT_LEN);
- if (!pkt) {
- pr_warn("Out of memory\n");
- return;
- }
- cfpkt_addbdy(pkt, CFCTRL_CMD_WAKE);
- init_info(cfpkt_info(pkt), cfctrl);
- ret =
- cfctrl->serv.layer.dn->transmit(cfctrl->serv.layer.dn, pkt);
- if (ret < 0)
- cfpkt_destroy(pkt);
-}
-
-void cfctrl_getstartreason_req(struct cflayer *layer)
-{
- int ret;
- struct cfctrl *cfctrl = container_obj(layer);
- struct cfpkt *pkt = cfpkt_create(CFPKT_CTRL_PKT_LEN);
- if (!pkt) {
- pr_warn("Out of memory\n");
- return;
- }
- cfpkt_addbdy(pkt, CFCTRL_CMD_START_REASON);
- init_info(cfpkt_info(pkt), cfctrl);
- ret =
- cfctrl->serv.layer.dn->transmit(cfctrl->serv.layer.dn, pkt);
- if (ret < 0)
- cfpkt_destroy(pkt);
-}
-
-
void cfctrl_cancel_req(struct cflayer *layr, struct cflayer *adap_layer)
{
struct cfctrl_request_info *p, *tmp;
--- a/net/caif/cfmuxl.c 2010-10-19 09:30:45.802913489 -0700
+++ b/net/caif/cfmuxl.c 2010-10-19 09:40:33.573416250 -0700
@@ -71,41 +71,6 @@ int cfmuxl_set_uplayer(struct cflayer *l
return 0;
}
-bool cfmuxl_is_phy_inuse(struct cflayer *layr, u8 phyid)
-{
- struct list_head *node;
- struct cflayer *layer;
- struct cfmuxl *muxl = container_obj(layr);
- bool match = false;
- spin_lock(&muxl->receive_lock);
-
- list_for_each(node, &muxl->srvl_list) {
- layer = list_entry(node, struct cflayer, node);
- if (cfsrvl_phyid_match(layer, phyid)) {
- match = true;
- break;
- }
-
- }
- spin_unlock(&muxl->receive_lock);
- return match;
-}
-
-u8 cfmuxl_get_phyid(struct cflayer *layr, u8 channel_id)
-{
- struct cflayer *up;
- int phyid;
- struct cfmuxl *muxl = container_obj(layr);
- spin_lock(&muxl->receive_lock);
- up = get_up(muxl, channel_id);
- if (up != NULL)
- phyid = cfsrvl_getphyid(up);
- else
- phyid = 0;
- spin_unlock(&muxl->receive_lock);
- return phyid;
-}
-
int cfmuxl_set_dnlayer(struct cflayer *layr, struct cflayer *dn, u8 phyid)
{
struct cfmuxl *muxl = (struct cfmuxl *) layr;
--- a/net/caif/cfpkt_skbuff.c 2010-10-19 09:31:38.804197063 -0700
+++ b/net/caif/cfpkt_skbuff.c 2010-10-19 09:42:03.710371120 -0700
@@ -42,22 +42,22 @@ struct cfpkt_priv_data {
bool erronous;
};
-inline struct cfpkt_priv_data *cfpkt_priv(struct cfpkt *pkt)
+static inline struct cfpkt_priv_data *cfpkt_priv(struct cfpkt *pkt)
{
return (struct cfpkt_priv_data *) pkt->skb.cb;
}
-inline bool is_erronous(struct cfpkt *pkt)
+static inline bool is_erronous(struct cfpkt *pkt)
{
return cfpkt_priv(pkt)->erronous;
}
-inline struct sk_buff *pkt_to_skb(struct cfpkt *pkt)
+static inline struct sk_buff *pkt_to_skb(struct cfpkt *pkt)
{
return &pkt->skb;
}
-inline struct cfpkt *skb_to_pkt(struct sk_buff *skb)
+static inline struct cfpkt *skb_to_pkt(struct sk_buff *skb)
{
return (struct cfpkt *) skb;
}
@@ -317,17 +317,6 @@ int cfpkt_setlen(struct cfpkt *pkt, u16
}
EXPORT_SYMBOL(cfpkt_setlen);
-struct cfpkt *cfpkt_create_uplink(const unsigned char *data, unsigned int len)
-{
- struct cfpkt *pkt = cfpkt_create_pfx(len + PKT_POSTFIX, PKT_PREFIX);
- if (!pkt)
- return NULL;
- if (unlikely(data != NULL))
- cfpkt_add_body(pkt, data, len);
- return pkt;
-}
-EXPORT_SYMBOL(cfpkt_create_uplink);
-
struct cfpkt *cfpkt_append(struct cfpkt *dstpkt,
struct cfpkt *addpkt,
u16 expectlen)
@@ -408,169 +397,12 @@ struct cfpkt *cfpkt_split(struct cfpkt *
}
EXPORT_SYMBOL(cfpkt_split);
-char *cfpkt_log_pkt(struct cfpkt *pkt, char *buf, int buflen)
-{
- struct sk_buff *skb = pkt_to_skb(pkt);
- char *p = buf;
- int i;
-
- /*
- * Sanity check buffer length, it needs to be at least as large as
- * the header info: ~=50+ bytes
- */
- if (buflen < 50)
- return NULL;
-
- snprintf(buf, buflen, "%s: pkt:%p len:%ld(%ld+%ld) {%ld,%ld} data: [",
- is_erronous(pkt) ? "ERRONOUS-SKB" :
- (skb->data_len != 0 ? "COMPLEX-SKB" : "SKB"),
- skb,
- (long) skb->len,
- (long) (skb_tail_pointer(skb) - skb->data),
- (long) skb->data_len,
- (long) (skb->data - skb->head),
- (long) (skb_tail_pointer(skb) - skb->head));
- p = buf + strlen(buf);
-
- for (i = 0; i < skb_tail_pointer(skb) - skb->data && i < 300; i++) {
- if (p > buf + buflen - 10) {
- sprintf(p, "...");
- p = buf + strlen(buf);
- break;
- }
- sprintf(p, "%02x,", skb->data[i]);
- p = buf + strlen(buf);
- }
- sprintf(p, "]\n");
- return buf;
-}
-EXPORT_SYMBOL(cfpkt_log_pkt);
-
-int cfpkt_raw_append(struct cfpkt *pkt, void **buf, unsigned int buflen)
-{
- struct sk_buff *skb = pkt_to_skb(pkt);
- struct sk_buff *lastskb;
-
- caif_assert(buf != NULL);
- if (unlikely(is_erronous(pkt)))
- return -EPROTO;
- /* Make sure SKB is writable */
- if (unlikely(skb_cow_data(skb, 0, &lastskb) < 0)) {
- PKT_ERROR(pkt, "skb_cow_data failed\n");
- return -EPROTO;
- }
-
- if (unlikely(skb_linearize(skb) != 0)) {
- PKT_ERROR(pkt, "linearize failed\n");
- return -EPROTO;
- }
-
- if (unlikely(skb_tailroom(skb) < buflen)) {
- PKT_ERROR(pkt, "buffer too short - failed\n");
- return -EPROTO;
- }
-
- *buf = skb_put(skb, buflen);
- return 1;
-}
-EXPORT_SYMBOL(cfpkt_raw_append);
-
-int cfpkt_raw_extract(struct cfpkt *pkt, void **buf, unsigned int buflen)
-{
- struct sk_buff *skb = pkt_to_skb(pkt);
-
- caif_assert(buf != NULL);
- if (unlikely(is_erronous(pkt)))
- return -EPROTO;
-
- if (unlikely(buflen > skb->len)) {
- PKT_ERROR(pkt, "buflen too large - failed\n");
- return -EPROTO;
- }
-
- if (unlikely(buflen > skb_headlen(skb))) {
- if (unlikely(skb_linearize(skb) != 0)) {
- PKT_ERROR(pkt, "linearize failed\n");
- return -EPROTO;
- }
- }
-
- *buf = skb->data;
- skb_pull(skb, buflen);
-
- return 1;
-}
-EXPORT_SYMBOL(cfpkt_raw_extract);
-
-inline bool cfpkt_erroneous(struct cfpkt *pkt)
+bool cfpkt_erroneous(struct cfpkt *pkt)
{
return cfpkt_priv(pkt)->erronous;
}
EXPORT_SYMBOL(cfpkt_erroneous);
-struct cfpktq *cfpktq_create(void)
-{
- struct cfpktq *q = kmalloc(sizeof(struct cfpktq), GFP_ATOMIC);
- if (!q)
- return NULL;
- skb_queue_head_init(&q->head);
- atomic_set(&q->count, 0);
- spin_lock_init(&q->lock);
- return q;
-}
-EXPORT_SYMBOL(cfpktq_create);
-
-void cfpkt_queue(struct cfpktq *pktq, struct cfpkt *pkt, unsigned short prio)
-{
- atomic_inc(&pktq->count);
- spin_lock(&pktq->lock);
- skb_queue_tail(&pktq->head, pkt_to_skb(pkt));
- spin_unlock(&pktq->lock);
-
-}
-EXPORT_SYMBOL(cfpkt_queue);
-
-struct cfpkt *cfpkt_qpeek(struct cfpktq *pktq)
-{
- struct cfpkt *tmp;
- spin_lock(&pktq->lock);
- tmp = skb_to_pkt(skb_peek(&pktq->head));
- spin_unlock(&pktq->lock);
- return tmp;
-}
-EXPORT_SYMBOL(cfpkt_qpeek);
-
-struct cfpkt *cfpkt_dequeue(struct cfpktq *pktq)
-{
- struct cfpkt *pkt;
- spin_lock(&pktq->lock);
- pkt = skb_to_pkt(skb_dequeue(&pktq->head));
- if (pkt) {
- atomic_dec(&pktq->count);
- caif_assert(atomic_read(&pktq->count) >= 0);
- }
- spin_unlock(&pktq->lock);
- return pkt;
-}
-EXPORT_SYMBOL(cfpkt_dequeue);
-
-int cfpkt_qcount(struct cfpktq *pktq)
-{
- return atomic_read(&pktq->count);
-}
-EXPORT_SYMBOL(cfpkt_qcount);
-
-struct cfpkt *cfpkt_clone_release(struct cfpkt *pkt)
-{
- struct cfpkt *clone;
- clone = skb_to_pkt(skb_clone(pkt_to_skb(pkt), GFP_ATOMIC));
- /* Free original packet. */
- cfpkt_destroy(pkt);
- if (!clone)
- return NULL;
- return clone;
-}
-EXPORT_SYMBOL(cfpkt_clone_release);
struct caif_payload_info *cfpkt_info(struct cfpkt *pkt)
{
--- a/net/caif/cfsrvl.c 2010-10-19 09:38:07.842929217 -0700
+++ b/net/caif/cfsrvl.c 2010-10-19 09:40:31.817241735 -0700
@@ -151,12 +151,7 @@ static int cfservl_modemcmd(struct cflay
return -EINVAL;
}
-void cfservl_destroy(struct cflayer *layer)
-{
- kfree(layer);
-}
-
-void cfsrvl_release(struct kref *kref)
+static void cfsrvl_release(struct kref *kref)
{
struct cfsrvl *service = container_of(kref, struct cfsrvl, ref);
kfree(service);
--- a/include/net/caif/cfmuxl.h 2010-10-19 09:25:53.761769361 -0700
+++ b/include/net/caif/cfmuxl.h 2010-10-19 09:39:23.178419722 -0700
@@ -16,7 +16,5 @@ int cfmuxl_set_uplayer(struct cflayer *l
struct cflayer *cfmuxl_remove_dnlayer(struct cflayer *layr, u8 phyid);
int cfmuxl_set_dnlayer(struct cflayer *layr, struct cflayer *up, u8 phyid);
struct cflayer *cfmuxl_remove_uplayer(struct cflayer *layr, u8 linkid);
-bool cfmuxl_is_phy_inuse(struct cflayer *layr, u8 phyid);
-u8 cfmuxl_get_phyid(struct cflayer *layr, u8 channel_id);
#endif /* CFMUXL_H_ */
--- a/include/net/caif/cfsrvl.h 2010-10-19 09:25:53.837776953 -0700
+++ b/include/net/caif/cfsrvl.h 2010-10-19 09:39:21.410243950 -0700
@@ -22,7 +22,6 @@ struct cfsrvl {
struct kref ref;
};
-void cfsrvl_release(struct kref *kref);
struct cflayer *cfvei_create(u8 linkid, struct dev_info *dev_info);
struct cflayer *cfdgml_create(u8 linkid, struct dev_info *dev_info);
struct cflayer *cfutill_create(u8 linkid, struct dev_info *dev_info);
@@ -31,7 +30,7 @@ struct cflayer *cfrfml_create(u8 linkid,
int mtu_size);
struct cflayer *cfdbgl_create(u8 linkid, struct dev_info *dev_info);
bool cfsrvl_phyid_match(struct cflayer *layer, int phyid);
-void cfservl_destroy(struct cflayer *layer);
+
void cfsrvl_init(struct cfsrvl *service,
u8 channel_id,
struct dev_info *dev_info,
--- a/net/caif/caif_config_util.c 2010-10-19 09:53:45.182003880 -0700
+++ b/net/caif/caif_config_util.c 2010-10-19 09:53:58.887283867 -0700
@@ -10,9 +10,9 @@
#include <net/caif/cfcnfg.h>
#include <net/caif/caif_dev.h>
-int connect_req_to_link_param(struct cfcnfg *cnfg,
- struct caif_connect_request *s,
- struct cfctrl_link_param *l)
+int caif_connect_req_to_link_param(struct cfcnfg *cnfg,
+ struct caif_connect_request *s,
+ struct cfctrl_link_param *l)
{
struct dev_info *dev_info;
enum cfcnfg_phy_preference pref;
^ permalink raw reply
* [PATCH 2/2] Revert napi_poll fix for bonding driver
From: nhorman @ 2010-10-19 17:04 UTC (permalink / raw)
To: netdev; +Cc: bonding-devel, fubar, davem, andy, amwang, nhorman
In-Reply-To: <1287507866-25156-1-git-send-email-nhorman@tuxdriver.com>
From: Neil Horman <nhorman@tuxdriver.com>
In an erlier patch I modified napi_poll so that devices with IFF_MASTER polled
the per_cpu list instead of the device list for napi. I did this because the
bonding driver has no napi instances to poll, it instead expects to check the
slave devices napi instances, which napi_poll was unaware of. Looking at this
more closely however, I now see this isn't strictly needed. As the bond driver
poll_controller calls the slaves poll_controller via netpoll_poll_dev, which
recursively calls poll_napi on each slave, allowing those napi instances to get
serviced. The earlier patch isn't at all harmfull, its just not needed, so lets
revert it to make the code cleaner. Sorry for the noise,
Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
---
net/core/netpoll.c | 9 +--------
1 files changed, 1 insertions(+), 8 deletions(-)
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index d79d221..4e98ffa 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -156,15 +156,8 @@ static void poll_napi(struct net_device *dev)
{
struct napi_struct *napi;
int budget = 16;
- struct softnet_data *sd = &__get_cpu_var(softnet_data);
- struct list_head *nlist;
- if (dev->flags & IFF_MASTER)
- nlist = &sd->poll_list;
- else
- nlist = &dev->napi_list;
-
- list_for_each_entry(napi, nlist, dev_list) {
+ list_for_each_entry(napi, &dev->napi_list, dev_list) {
if (napi->poll_owner != smp_processor_id() &&
spin_trylock(&napi->poll_lock)) {
budget = poll_one_napi(dev->npinfo, napi, budget);
--
1.7.2.3
^ permalink raw reply related
* [PATCH 1/2] Remove netpoll blocking from uninit path
From: nhorman @ 2010-10-19 17:04 UTC (permalink / raw)
To: netdev; +Cc: bonding-devel, fubar, davem, andy, amwang, nhorman
In-Reply-To: <1287507866-25156-1-git-send-email-nhorman@tuxdriver.com>
From: Neil Horman <nhorman@tuxdriver.com>
Some recent testing in netpoll with bonding showed this backtrace
------------[ cut here ]------------
kernel BUG at drivers/net/bonding/bonding.h:134!
invalid opcode: 0000 [#1] SMP
last sysfs file: /sys/devices/pci0000:00/0000:00:1d.2/usb7/devnum
CPU 0
Pid: 1876, comm: rmmod Not tainted 2.6.36-rc3+ #10 D26928/
RIP: 0010:[<ffffffffa0514ba4>] [<ffffffffa0514ba4>] bond_uninit+0x6f4/0x7a0
RSP: 0018:ffff88003b1b5d58 EFLAGS: 00010296
RAX: ffff88003b9b6200 RBX: ffff8800373e8e00 RCX: 00000000000f4240
RDX: 00000000ffffffff RSI: 0000000000000286 RDI: 0000000000000286
RBP: ffff88003b1b5dc8 R08: 0000000000000000 R09: 00000001af7de920
R10: 0000000000000000 R11: ffff880002495e98 R12: ffff880037922700
R13: ffff880038c31000 R14: ffff880037922730 R15: 0000000000000286
FS: 00007f90e6d72700(0000) GS:ffff880002400000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b
CR2: 000000346f0d9ad0 CR3: 000000003b263000 CR4: 00000000000006f0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
Process rmmod (pid: 1876, threadinfo ffff88003b1b4000, task ffff88003b36aa80)
Stack:
00000000ffffffff ffff88003b1b5d7a ffff8800379221e8 ffff880037922000
<0> ffff88003b1b5dc8 ffffffff813eb5fb ffff88003b1b5da8 0000000031b177a3
<0> ffff88003b1b5da8 ffff880037922000 ffff88003b1b5e48 ffff88003b1b5e48
Call Trace:
[<ffffffff813eb5fb>] ? rtmsg_ifinfo+0xcb/0xf0
[<ffffffff813daad8>] rollback_registered_many+0x168/0x280
[<ffffffff813dac09>] unregister_netdevice_many+0x19/0x80
[<ffffffff813e97b3>] __rtnl_kill_links+0x63/0x90
[<ffffffff813e980b>] __rtnl_link_unregister+0x2b/0x60
[<ffffffff813e9bde>] rtnl_link_unregister+0x1e/0x30
[<ffffffffa052124b>] bonding_exit+0x37/0x51 [bonding]
[<ffffffff81098b2e>] sys_delete_module+0x19e/0x270
[<ffffffff810bb2b2>] ? audit_syscall_entry+0x252/0x280
[<ffffffff8100b0b2>] system_call_fastpath+0x16/0x1b
RIP [<ffffffffa0514ba4>] bond_uninit+0x6f4/0x7a0 [bonding]
RSP <ffff88003b1b5d58>
---[ end trace 1395ad691cea24d1 ]---
It occurs because of my recent netpoll blocking patches, which I added to avoid
recursive deadlock in the bonding driver. It relies on some per cpu bits, but
the shutdown path forces some rescheduling as we cancel workqueues for the
driver and wait for some device refcounts. If after the forced reschedule, we
wind up on a different cpu we trigger the bughalt in unblock_netpoll_tx.
The fix is to remove the netpoll block/unblock calls from bond_release_all.
This is safe to do because bond_uninit, which is called via ndo_uninit in
rollback_registered_many, doesn't occur until we send a NETDEV_UNREGISTER event,
which triggers netconsole to remove us as a netpoll client, so we are guaranteed
not to recurse into our own tx path here.
Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
---
drivers/net/bonding/bond_main.c | 3 ---
1 files changed, 0 insertions(+), 3 deletions(-)
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 38d4ca0..99cb891 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -2082,7 +2082,6 @@ static int bond_release_all(struct net_device *bond_dev)
struct net_device *slave_dev;
struct sockaddr addr;
- block_netpoll_tx();
write_lock_bh(&bond->lock);
netif_carrier_off(bond_dev);
@@ -2181,8 +2180,6 @@ static int bond_release_all(struct net_device *bond_dev)
out:
write_unlock_bh(&bond->lock);
- unblock_netpoll_tx();
-
return 0;
}
--
1.7.2.3
^ permalink raw reply related
* [PATCH] bonding: minor cleanups to bond + netpoll
From: nhorman @ 2010-10-19 17:04 UTC (permalink / raw)
To: netdev; +Cc: bonding-devel, fubar, davem, andy, amwang, nhorman
Testing that was onging when the the reset patchset to enable netpoll over
bonding revealed some minor corner cases that are worth correcting. In summary:
1) Remove netpoll tx blocking from bond_release_all. Its not needed and causes
some uglyness when removing the bonding module, in the form of a backtrace that
gets logged. blocking isn't needed in this path anyway as the netconsole is
already unregistered from us at this point
2) Remove my changes to napi_poll. Closer inspection of the bonding
poll_controller show that we wind up recursively calling the napi poll routines
for the slaves through sucsessive calls to netpoll_poll_dev. My origional
change is harmless, but its not really needed, so lets make the code simpler.
Further details available in the individual commit messages
Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
^ permalink raw reply
* Re: [PATCH net-next] bnx2: Increase max rx ring size from 1K to 2K
From: Michael Chan @ 2010-10-19 17:03 UTC (permalink / raw)
To: David Miller
Cc: andy@greyhouse.net, jfeeney@redhat.com, netdev@vger.kernel.org
In-Reply-To: <20101019.011434.226774173.davem@davemloft.net>
On Tue, 2010-10-19 at 01:14 -0700, David Miller wrote:
> From: "Michael Chan" <mchan@broadcom.com>
> Date: Mon, 18 Oct 2010 17:30:54 -0700
>
> > A number of customers are reporting packet loss under certain workloads
> > (e.g. heavy bursts of small packets) with flow control disabled. A larger
> > rx ring helps to prevent these losses.
> >
> > No change in default rx ring size and memory consumption.
> >
> > Signed-off-by: Andy Gospodarek <andy@greyhouse.net>
> > Acked-by: John Feeney <jfeeney@redhat.com>
> > Signed-off-by: Michael Chan <mchan@broadcom.com>
>
> I don't see how it's any better to queue things more deeply in
> hardware, compared to simply using hardware flow control since that's
> what it's for and makes the queuing happen in the networking stack of
> the sender, in software, which in the end performs better and gives
> better feedback to the source of the data.
There are situations where flow control is not desirable. For example,
if there are many multicast receivers in the network, you may not want a
few slow receivers to slow down the entire network with flow control.
>
> These huge RX queue sizes are absolutely rediculious, and I've
> complained about this before.
Yes you have and I was initially hesitant to post this patch. But the
customer sees that many other 1G drivers in the tree can have bigger
ring sizes and as a result, they have fewer packet drops using these
other devices. In fact, 2K is still much smaller than many other 1G
drivers in the tree. Please also note that this does not add any extra
memory to the default configuration. Thanks.
>
> And instead of seeing less of this, I keep seeing more of this stuff.
> Please exert some pushback on these folks who are doing such insane
> things.
>
> Thanks.
>
^ permalink raw reply
* [PATCH] macb: Don't re-enable interrupts while in polling mode
From: Joshua Hoke @ 2010-10-19 16:48 UTC (permalink / raw)
To: Nicolas Ferre
Cc: David S. Miller, Jiri Pirko, Peter Korsgaard, Eric Dumazet,
Haavard Skinnemoen, netdev, linux-kernel, Andrew Morton
From: Joshua Hoke <joshua.hoke@sixnet.com>
[PATCH] macb: Don't re-enable interrupts while in polling mode
On a busy network, the macb driver could get stuck in the interrupt
handler, quickly triggering the watchdog, due to a confluence of
factors:
1. macb_poll re-enables interrupts unconditionally, even when it will
be called again because it exhausted its rx budget
2. macb_interrupt only disables interrupts after scheduling
macb_poll, but scheduling fails when macb_poll is already scheduled
because it didn't call napi_complete
3. macb_interrupt loops until the interrupt status register is clear,
which will never happen in this case if the driver doesn't disable
the RX interrupt
Since macb_interrupt runs in interrupt context, this effectively locks
up the machine, triggering the hardware watchdog.
This issue was readily reproducible on a flooded network with a
modified 2.6.27.48 kernel. The same problem appears to still be in the
2.6.36-rc8 driver code, so I am submitting this patch against that
version. I have not tested this version of the patch except to make
sure the kernel compiles.
Signed-off-by: Joshua Hoke <joshua.hoke@sixnet.com>
---
I'm submitting this at the request of Andrew Morton in this bug:
https://bugzilla.kernel.org/show_bug.cgi?id=20732
This version of the patch applies to 2.6.36-rc8 but has not been
tested. In particular I am assuming that napi_schedule_prep() behaves
the same as netif_rx_schedule_prep() did by failing when the macb_poll
callback is already scheduled.
diff --git a/drivers/net/macb.c b/drivers/net/macb.c
index ff2f158..36cf594 100644
--- a/drivers/net/macb.c
+++ b/drivers/net/macb.c
@@ -515,14 +515,15 @@ static int macb_poll(struct napi_struct *napi, int
budget)
(unsigned long)status, budget);
work_done = macb_rx(bp, budget);
- if (work_done < budget)
+ if (work_done < budget) {
napi_complete(napi);
- /*
- * We've done what we can to clean the buffers. Make sure we
- * get notified when new packets arrive.
- */
- macb_writel(bp, IER, MACB_RX_INT_FLAGS);
+ /*
+ * We've done what we can to clean the buffers. Make
sure we
+ * get notified when new packets arrive.
+ */
+ macb_writel(bp, IER, MACB_RX_INT_FLAGS);
+ }
/* TODO: Handle errors */
@@ -550,12 +551,16 @@ static irqreturn_t macb_interrupt(int irq, void
*dev_id)
}
if (status & MACB_RX_INT_FLAGS) {
+ /*
+ * There's no point taking any more interrupts
+ * until we have processed the buffers. The
+ * scheduling call may fail if the poll routine
+ * is already scheduled, so disable interrupts
+ * now.
+ */
+ macb_writel(bp, IDR, MACB_RX_INT_FLAGS);
+
if (napi_schedule_prep(&bp->napi)) {
- /*
- * There's no point taking any more
interrupts
- * until we have processed the buffers
- */
- macb_writel(bp, IDR, MACB_RX_INT_FLAGS);
dev_dbg(&bp->pdev->dev,
"scheduling RX softirq\n");
__napi_schedule(&bp->napi);
^ permalink raw reply related
* [PATCH net-next] napi: unexport napi_reuse_skb
From: Stephen Hemminger @ 2010-10-19 17:12 UTC (permalink / raw)
To: David Miller; +Cc: netdev
The function napi_reuse_skb is only used inside core.
Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
---
include/linux/netdevice.h | 2 --
net/core/dev.c | 3 +--
2 files changed, 1 insertion(+), 4 deletions(-)
--- a/include/linux/netdevice.h 2010-10-19 09:03:13.211106810 -0700
+++ b/include/linux/netdevice.h 2010-10-19 09:03:24.568216914 -0700
@@ -1745,8 +1745,6 @@ extern gro_result_t napi_skb_finish(gro_
extern gro_result_t napi_gro_receive(struct napi_struct *napi,
struct sk_buff *skb);
extern void napi_gro_flush(struct napi_struct *napi);
-extern void napi_reuse_skb(struct napi_struct *napi,
- struct sk_buff *skb);
extern struct sk_buff * napi_get_frags(struct napi_struct *napi);
extern gro_result_t napi_frags_finish(struct napi_struct *napi,
struct sk_buff *skb,
--- a/net/core/dev.c 2010-10-19 09:03:13.235109156 -0700
+++ b/net/core/dev.c 2010-10-19 09:03:58.839566666 -0700
@@ -3287,14 +3287,13 @@ gro_result_t napi_gro_receive(struct nap
}
EXPORT_SYMBOL(napi_gro_receive);
-void napi_reuse_skb(struct napi_struct *napi, struct sk_buff *skb)
+static void napi_reuse_skb(struct napi_struct *napi, struct sk_buff *skb)
{
__skb_pull(skb, skb_headlen(skb));
skb_reserve(skb, NET_IP_ALIGN - skb_headroom(skb));
napi->skb = skb;
}
-EXPORT_SYMBOL(napi_reuse_skb);
struct sk_buff *napi_get_frags(struct napi_struct *napi)
{
^ permalink raw reply
* [PATCH net-next] rds: make local functions/variables static
From: Stephen Hemminger @ 2010-10-19 18:08 UTC (permalink / raw)
To: Andy Grover, Zach Brown, Chris Mason, David Miller; +Cc: rds-devel, netdev
The RDS protocol has lots of functions that should be
declared static. rds_message_get/add_version_extension is
removed since it defined but never used.
Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
---
net/rds/connection.c | 2 +-
net/rds/ib.c | 10 +++++-----
net/rds/ib.h | 4 ----
net/rds/ib_rdma.c | 2 +-
net/rds/ib_sysctl.c | 2 +-
net/rds/iw.c | 4 ++--
net/rds/iw.h | 4 ----
net/rds/iw_rdma.c | 3 ++-
net/rds/iw_sysctl.c | 2 +-
net/rds/message.c | 24 ++----------------------
net/rds/page.c | 3 ++-
net/rds/rdma_transport.c | 4 ++--
net/rds/rdma_transport.h | 4 ----
net/rds/rds.h | 5 -----
net/rds/recv.c | 3 +--
net/rds/send.c | 4 +++-
net/rds/tcp.c | 6 +++---
net/rds/tcp.h | 2 --
net/rds/tcp_recv.c | 3 ++-
net/rds/tcp_send.c | 2 +-
20 files changed, 29 insertions(+), 64 deletions(-)
--- a/net/rds/connection.c 2010-10-19 10:36:00.346844139 -0700
+++ b/net/rds/connection.c 2010-10-19 10:50:24.678156846 -0700
@@ -88,7 +88,7 @@ static struct rds_connection *rds_conn_l
* and receiving over this connection again in the future. It is up to
* the transport to have serialized this call with its send and recv.
*/
-void rds_conn_reset(struct rds_connection *conn)
+static void rds_conn_reset(struct rds_connection *conn)
{
rdsdebug("connection %pI4 to %pI4 reset\n",
&conn->c_laddr, &conn->c_faddr);
--- a/net/rds/ib.c 2010-10-19 10:36:24.489145829 -0700
+++ b/net/rds/ib.c 2010-10-19 10:38:05.034732462 -0700
@@ -42,7 +42,7 @@
#include "rds.h"
#include "ib.h"
-unsigned int fmr_pool_size = RDS_FMR_POOL_SIZE;
+static unsigned int fmr_pool_size = RDS_FMR_POOL_SIZE;
unsigned int fmr_message_size = RDS_FMR_SIZE + 1; /* +1 allows for unaligned MRs */
unsigned int rds_ib_retry_count = RDS_IB_DEFAULT_RETRY_COUNT;
@@ -65,7 +65,7 @@ struct list_head rds_ib_devices;
DEFINE_SPINLOCK(ib_nodev_conns_lock);
LIST_HEAD(ib_nodev_conns);
-void rds_ib_nodev_connect(void)
+static void rds_ib_nodev_connect(void)
{
struct rds_ib_connection *ic;
@@ -75,7 +75,7 @@ void rds_ib_nodev_connect(void)
spin_unlock(&ib_nodev_conns_lock);
}
-void rds_ib_dev_shutdown(struct rds_ib_device *rds_ibdev)
+static void rds_ib_dev_shutdown(struct rds_ib_device *rds_ibdev)
{
struct rds_ib_connection *ic;
unsigned long flags;
@@ -118,7 +118,7 @@ void rds_ib_dev_put(struct rds_ib_device
queue_work(rds_wq, &rds_ibdev->free_work);
}
-void rds_ib_add_one(struct ib_device *device)
+static void rds_ib_add_one(struct ib_device *device)
{
struct rds_ib_device *rds_ibdev;
struct ib_device_attr *dev_attr;
@@ -229,7 +229,7 @@ struct rds_ib_device *rds_ib_get_client_
*
* This can be called at any time and can be racing with any other RDS path.
*/
-void rds_ib_remove_one(struct ib_device *device)
+static void rds_ib_remove_one(struct ib_device *device)
{
struct rds_ib_device *rds_ibdev;
--- a/net/rds/ib.h 2010-10-19 10:37:19.938432563 -0700
+++ b/net/rds/ib.h 2010-10-19 10:53:22.118325615 -0700
@@ -265,13 +265,10 @@ static inline void rds_ib_dma_sync_sg_fo
/* ib.c */
extern struct rds_transport rds_ib_transport;
-extern void rds_ib_add_one(struct ib_device *device);
-extern void rds_ib_remove_one(struct ib_device *device);
struct rds_ib_device *rds_ib_get_client_data(struct ib_device *device);
void rds_ib_dev_put(struct rds_ib_device *rds_ibdev);
extern struct ib_client rds_ib_client;
-extern unsigned int fmr_pool_size;
extern unsigned int fmr_message_size;
extern unsigned int rds_ib_retry_count;
@@ -374,6 +371,5 @@ extern unsigned long rds_ib_sysctl_max_u
extern unsigned long rds_ib_sysctl_max_unsig_bytes;
extern unsigned long rds_ib_sysctl_max_recv_allocation;
extern unsigned int rds_ib_sysctl_flow_control;
-extern ctl_table rds_ib_sysctl_table[];
#endif
--- a/net/rds/ib_rdma.c 2010-10-19 10:38:36.109695644 -0700
+++ b/net/rds/ib_rdma.c 2010-10-19 10:38:43.474397946 -0700
@@ -38,7 +38,7 @@
#include "ib.h"
#include "xlist.h"
-struct workqueue_struct *rds_ib_fmr_wq;
+static struct workqueue_struct *rds_ib_fmr_wq;
static DEFINE_PER_CPU(unsigned long, clean_list_grace);
#define CLEAN_LIST_BUSY_BIT 0
--- a/net/rds/ib_sysctl.c 2010-10-19 10:39:22.998166930 -0700
+++ b/net/rds/ib_sysctl.c 2010-10-19 10:39:45.780252357 -0700
@@ -61,7 +61,7 @@ static unsigned long rds_ib_sysctl_max_u
*/
unsigned int rds_ib_sysctl_flow_control = 0;
-ctl_table rds_ib_sysctl_table[] = {
+static ctl_table rds_ib_sysctl_table[] = {
{
.procname = "max_send_wr",
.data = &rds_ib_sysctl_max_send_wr,
--- a/net/rds/iw.c 2010-10-19 10:40:14.130811167 -0700
+++ b/net/rds/iw.c 2010-10-19 10:40:40.601201008 -0700
@@ -56,7 +56,7 @@ struct list_head rds_iw_devices;
DEFINE_SPINLOCK(iw_nodev_conns_lock);
LIST_HEAD(iw_nodev_conns);
-void rds_iw_add_one(struct ib_device *device)
+static void rds_iw_add_one(struct ib_device *device)
{
struct rds_iw_device *rds_iwdev;
struct ib_device_attr *dev_attr;
@@ -124,7 +124,7 @@ free_attr:
kfree(dev_attr);
}
-void rds_iw_remove_one(struct ib_device *device)
+static void rds_iw_remove_one(struct ib_device *device)
{
struct rds_iw_device *rds_iwdev;
struct rds_iw_cm_id *i_cm_id, *next;
--- a/net/rds/iw.h 2010-10-19 10:53:48.052691754 -0700
+++ b/net/rds/iw.h 2010-10-19 10:54:09.078609969 -0700
@@ -268,8 +268,6 @@ static inline u32 rds_iw_local_dma_lkey(
/* ib.c */
extern struct rds_transport rds_iw_transport;
-extern void rds_iw_add_one(struct ib_device *device);
-extern void rds_iw_remove_one(struct ib_device *device);
extern struct ib_client rds_iw_client;
extern unsigned int fastreg_pool_size;
@@ -318,7 +316,6 @@ void *rds_iw_get_mr(struct scatterlist *
void rds_iw_sync_mr(void *trans_private, int dir);
void rds_iw_free_mr(void *trans_private, int invalidate);
void rds_iw_flush_mrs(void);
-void rds_iw_remove_cm_id(struct rds_iw_device *rds_iwdev, struct rdma_cm_id *cm_id);
/* ib_recv.c */
int rds_iw_recv_init(void);
@@ -378,7 +375,6 @@ extern unsigned long rds_iw_sysctl_max_u
extern unsigned long rds_iw_sysctl_max_unsig_bytes;
extern unsigned long rds_iw_sysctl_max_recv_allocation;
extern unsigned int rds_iw_sysctl_flow_control;
-extern ctl_table rds_iw_sysctl_table[];
/*
* Helper functions for getting/setting the header and data SGEs in
--- a/net/rds/iw_rdma.c 2010-10-19 10:40:49.237980581 -0700
+++ b/net/rds/iw_rdma.c 2010-10-19 10:40:58.058777701 -0700
@@ -157,7 +157,8 @@ static int rds_iw_add_cm_id(struct rds_i
return 0;
}
-void rds_iw_remove_cm_id(struct rds_iw_device *rds_iwdev, struct rdma_cm_id *cm_id)
+static void rds_iw_remove_cm_id(struct rds_iw_device *rds_iwdev,
+ struct rdma_cm_id *cm_id)
{
struct rds_iw_cm_id *i_cm_id;
--- a/net/rds/iw_sysctl.c 2010-10-19 10:41:15.516354119 -0700
+++ b/net/rds/iw_sysctl.c 2010-10-19 10:43:10.922788525 -0700
@@ -55,7 +55,7 @@ static unsigned long rds_iw_sysctl_max_u
unsigned int rds_iw_sysctl_flow_control = 1;
-ctl_table rds_iw_sysctl_table[] = {
+static ctl_table rds_iw_sysctl_table[] = {
{
.procname = "max_send_wr",
.data = &rds_iw_sysctl_max_send_wr,
--- a/net/rds/message.c 2010-10-19 10:43:34.584930068 -0700
+++ b/net/rds/message.c 2010-10-19 10:59:47.121527590 -0700
@@ -106,8 +106,8 @@ void rds_message_populate_header(struct
}
EXPORT_SYMBOL_GPL(rds_message_populate_header);
-int rds_message_add_extension(struct rds_header *hdr,
- unsigned int type, const void *data, unsigned int len)
+int rds_message_add_extension(struct rds_header *hdr, unsigned int type,
+ const void *data, unsigned int len)
{
unsigned int ext_len = sizeof(u8) + len;
unsigned char *dst;
@@ -177,26 +177,6 @@ none:
return RDS_EXTHDR_NONE;
}
-int rds_message_add_version_extension(struct rds_header *hdr, unsigned int version)
-{
- struct rds_ext_header_version ext_hdr;
-
- ext_hdr.h_version = cpu_to_be32(version);
- return rds_message_add_extension(hdr, RDS_EXTHDR_VERSION, &ext_hdr, sizeof(ext_hdr));
-}
-
-int rds_message_get_version_extension(struct rds_header *hdr, unsigned int *version)
-{
- struct rds_ext_header_version ext_hdr;
- unsigned int pos = 0, len = sizeof(ext_hdr);
-
- /* We assume the version extension is the only one present */
- if (rds_message_next_extension(hdr, &pos, &ext_hdr, &len) != RDS_EXTHDR_VERSION)
- return 0;
- *version = be32_to_cpu(ext_hdr.h_version);
- return 1;
-}
-
int rds_message_add_rdma_dest_extension(struct rds_header *hdr, u32 r_key, u32 offset)
{
struct rds_ext_header_rdma_dest ext_hdr;
--- a/net/rds/rdma_transport.c 2010-10-19 10:44:45.687369510 -0700
+++ b/net/rds/rdma_transport.c 2010-10-19 10:45:03.729004485 -0700
@@ -207,7 +207,7 @@ static void rds_rdma_listen_stop(void)
}
}
-int rds_rdma_init(void)
+static int rds_rdma_init(void)
{
int ret;
@@ -234,7 +234,7 @@ out:
}
module_init(rds_rdma_init);
-void rds_rdma_exit(void)
+static void rds_rdma_exit(void)
{
/* stop listening first to ensure no new connections are attempted */
rds_rdma_listen_stop();
--- a/net/rds/rdma_transport.h 2010-10-19 10:53:05.556814850 -0700
+++ b/net/rds/rdma_transport.h 2010-10-19 10:53:17.429897281 -0700
@@ -11,10 +11,6 @@ int rds_rdma_conn_connect(struct rds_con
int rds_rdma_cm_event_handler(struct rdma_cm_id *cm_id,
struct rdma_cm_event *event);
-/* from rdma_transport.c */
-int rds_rdma_init(void);
-void rds_rdma_exit(void);
-
/* from ib.c */
extern struct rds_transport rds_ib_transport;
int rds_ib_init(void);
--- a/net/rds/rds.h 2010-10-19 10:46:16.483601811 -0700
+++ b/net/rds/rds.h 2010-10-19 10:59:20.875122353 -0700
@@ -619,7 +619,6 @@ struct rds_connection *rds_conn_create_o
struct rds_transport *trans, gfp_t gfp);
void rds_conn_shutdown(struct rds_connection *conn);
void rds_conn_destroy(struct rds_connection *conn);
-void rds_conn_reset(struct rds_connection *conn);
void rds_conn_drop(struct rds_connection *conn);
void rds_conn_connect_if_down(struct rds_connection *conn);
void rds_for_each_conn_info(struct socket *sock, unsigned int len,
@@ -668,8 +667,6 @@ int rds_message_add_extension(struct rds
unsigned int type, const void *data, unsigned int len);
int rds_message_next_extension(struct rds_header *hdr,
unsigned int *pos, void *buf, unsigned int *buflen);
-int rds_message_add_version_extension(struct rds_header *hdr, unsigned int version);
-int rds_message_get_version_extension(struct rds_header *hdr, unsigned int *version);
int rds_message_add_rdma_dest_extension(struct rds_header *hdr, u32 r_key, u32 offset);
int rds_message_inc_copy_to_user(struct rds_incoming *inc,
struct iovec *first_iov, size_t size);
@@ -706,7 +703,6 @@ void rds_page_exit(void);
/* recv.c */
void rds_inc_init(struct rds_incoming *inc, struct rds_connection *conn,
__be32 saddr);
-void rds_inc_addref(struct rds_incoming *inc);
void rds_inc_put(struct rds_incoming *inc);
void rds_recv_incoming(struct rds_connection *conn, __be32 saddr, __be32 daddr,
struct rds_incoming *inc, gfp_t gfp, enum km_type km);
@@ -728,7 +724,6 @@ void rds_send_drop_to(struct rds_sock *r
typedef int (*is_acked_func)(struct rds_message *rm, uint64_t ack);
void rds_send_drop_acked(struct rds_connection *conn, u64 ack,
is_acked_func is_acked);
-void rds_send_remove_from_sock(struct list_head *messages, int status);
int rds_send_pong(struct rds_connection *conn, __be16 dport);
struct rds_message *rds_send_get_message(struct rds_connection *,
struct rm_rdma_op *);
--- a/net/rds/recv.c 2010-10-19 10:45:14.810008886 -0700
+++ b/net/rds/recv.c 2010-10-19 10:45:35.707903271 -0700
@@ -48,12 +48,11 @@ void rds_inc_init(struct rds_incoming *i
}
EXPORT_SYMBOL_GPL(rds_inc_init);
-void rds_inc_addref(struct rds_incoming *inc)
+static void rds_inc_addref(struct rds_incoming *inc)
{
rdsdebug("addref inc %p ref %d\n", inc, atomic_read(&inc->i_refcount));
atomic_inc(&inc->i_refcount);
}
-EXPORT_SYMBOL_GPL(rds_inc_addref);
void rds_inc_put(struct rds_incoming *inc)
{
--- a/net/rds/send.c 2010-10-19 10:45:43.272589570 -0700
+++ b/net/rds/send.c 2010-10-19 10:46:36.589425686 -0700
@@ -52,6 +52,8 @@ static int send_batch_count = 64;
module_param(send_batch_count, int, 0444);
MODULE_PARM_DESC(send_batch_count, " batch factor when working the send queue");
+static void rds_send_remove_from_sock(struct list_head *messages, int status);
+
/*
* Reset the send state. Callers must ensure that this doesn't race with
* rds_send_xmit().
@@ -555,7 +557,7 @@ EXPORT_SYMBOL_GPL(rds_send_get_message);
* removing the messages from the 'messages' list regardless of if it found
* the messages on the socket list or not.
*/
-void rds_send_remove_from_sock(struct list_head *messages, int status)
+static void rds_send_remove_from_sock(struct list_head *messages, int status)
{
unsigned long flags;
struct rds_sock *rs = NULL;
--- a/net/rds/tcp.c 2010-10-19 10:46:52.450865841 -0700
+++ b/net/rds/tcp.c 2010-10-19 10:47:54.492499537 -0700
@@ -41,7 +41,7 @@
/* only for info exporting */
static DEFINE_SPINLOCK(rds_tcp_tc_list_lock);
static LIST_HEAD(rds_tcp_tc_list);
-unsigned int rds_tcp_tc_count;
+static unsigned int rds_tcp_tc_count;
/* Track rds_tcp_connection structs so they can be cleaned up */
static DEFINE_SPINLOCK(rds_tcp_conn_lock);
@@ -243,7 +243,7 @@ static void rds_tcp_destroy_conns(void)
}
}
-void rds_tcp_exit(void)
+static void rds_tcp_exit(void)
{
rds_info_deregister_func(RDS_INFO_TCP_SOCKETS, rds_tcp_tc_info);
rds_tcp_listen_stop();
@@ -274,7 +274,7 @@ struct rds_transport rds_tcp_transport =
.t_prefer_loopback = 1,
};
-int rds_tcp_init(void)
+static int rds_tcp_init(void)
{
int ret;
--- a/net/rds/tcp.h 2010-10-19 10:54:15.559202132 -0700
+++ b/net/rds/tcp.h 2010-10-19 10:55:08.212010108 -0700
@@ -43,8 +43,6 @@ struct rds_tcp_statistics {
};
/* tcp.c */
-int rds_tcp_init(void);
-void rds_tcp_exit(void);
void rds_tcp_tune(struct socket *sock);
void rds_tcp_nonagle(struct socket *sock);
void rds_tcp_set_callbacks(struct socket *sock, struct rds_connection *conn);
--- a/net/rds/tcp_recv.c 2010-10-19 10:48:47.077278176 -0700
+++ b/net/rds/tcp_recv.c 2010-10-19 10:48:59.814436186 -0700
@@ -272,7 +272,8 @@ out:
}
/* the caller has to hold the sock lock */
-int rds_tcp_read_sock(struct rds_connection *conn, gfp_t gfp, enum km_type km)
+static int rds_tcp_read_sock(struct rds_connection *conn, gfp_t gfp,
+ enum km_type km)
{
struct rds_tcp_connection *tc = conn->c_transport_data;
struct socket *sock = tc->t_sock;
--- a/net/rds/tcp_send.c 2010-10-19 10:49:25.756795362 -0700
+++ b/net/rds/tcp_send.c 2010-10-19 10:49:40.974179535 -0700
@@ -63,7 +63,7 @@ void rds_tcp_xmit_complete(struct rds_co
}
/* the core send_sem serializes this with other xmit and shutdown */
-int rds_tcp_sendmsg(struct socket *sock, void *data, unsigned int len)
+static int rds_tcp_sendmsg(struct socket *sock, void *data, unsigned int len)
{
struct kvec vec = {
.iov_base = data,
--- a/net/rds/page.c 2010-10-19 11:00:18.352389347 -0700
+++ b/net/rds/page.c 2010-10-19 11:01:04.412612535 -0700
@@ -40,7 +40,8 @@ struct rds_page_remainder {
unsigned long r_offset;
};
-DEFINE_PER_CPU_SHARED_ALIGNED(struct rds_page_remainder, rds_page_remainders);
+static DEFINE_PER_CPU_SHARED_ALIGNED(struct rds_page_remainder,
+ rds_page_remainders);
/*
* returns 0 on success or -errno on failure.
^ permalink raw reply
* Re: [Ksummit-2010-discuss] [v2] Remaining BKL users, what to do
From: Valdis.Kletnieks @ 2010-10-19 18:24 UTC (permalink / raw)
To: Greg KH
Cc: Dave Airlie, Arnd Bergmann, codalist, ksummit-2010-discuss,
autofs, Jan Harkes, Samuel Ortiz, Jan Kara,
Arnaldo Carvalho de Melo, netdev, Anders Larsen, linux-kernel,
dri-devel, Bryan Schumaker, Christoph Hellwig, Petr Vandrovec,
Mikulas Patocka, linux-fsdevel, Evgeniy Dushistov, Ingo Molnar,
Andrew Hendry, linux-media
In-Reply-To: <20101019004004.GB28380@kroah.com>
[-- Attachment #1: Type: text/plain, Size: 939 bytes --]
On Mon, 18 Oct 2010 17:40:04 PDT, Greg KH said:
> I do have access to this hardware, but its on an old single processor
> laptop, so any work that it would take to help do this development,
> really wouldn't be able to be tested to be valid at all.
The i810 is a graphics chipset embedded on the memory controller, which
was designed for the Intel Pentium II, Pentium III, and Celeron CPUs. Page 8
of the datasheet specifically says:
Processor/Host Bus Support
- Optimized for the Intel Pentium II processor, Intel Pentium III processor, and Intel
CeleronTM processor
- Supports processor 370-Pin Socket and SC242
connectors
- Supports 32-Bit System Bus Addressing
- 4 deep in-order queue; 4 or 1 deep request queue
- Supports Uni-processor systems only
So no need to clean it up for multiprocessor support.
http://download.intel.com/design/chipsets/datashts/29067602.pdf
http://www.intel.com/design/chipsets/specupdt/29069403.pdf
[-- Attachment #2: Type: application/pgp-signature, Size: 227 bytes --]
^ permalink raw reply
* Re: [RFC PATCH 1/9] ipvs network name space aware
From: Paul E. McKenney @ 2010-10-19 18:44 UTC (permalink / raw)
To: Hans Schillstrom
Cc: Daniel Lezcano, lvs-devel@vger.kernel.org, netdev@vger.kernel.org,
netfilter-devel@vger.kernel.org, horms@verge.net.au, ja@ssi.bg,
wensong@linux-vs.org
In-Reply-To: <201010181523.49568.hans.schillstrom@ericsson.com>
On Mon, Oct 18, 2010 at 03:23:48PM +0200, Hans Schillstrom wrote:
> On Monday 18 October 2010 13:37:38 Daniel Lezcano wrote:
> > On 10/18/2010 11:54 AM, Hans Schillstrom wrote:
> > > On Monday 18 October 2010 10:59:25 Daniel Lezcano wrote:
> > >
> > >> On 10/08/2010 01:16 PM, Hans Schillstrom wrote:
> > >>
> > >>> This part contains the include files
> > >>> where include/net/netns/ip_vs.h is new and contains all moved vars.
> > >>>
> > >>> SUMMARY
> > >>>
> > >>> include/net/ip_vs.h | 136 ++++---
> > >>> include/net/net_namespace.h | 2 +
> > >>> include/net/netns/ip_vs.h | 112 +++++
> > >>>
> > >>> Signed-off-by:Hans Schillstrom<hans.schillstrom@ericsson.com>
> > >>> ---
> > >>>
> > >>>
> > >>>
> > >> [ ... ]
> > >>
> > >>
> > >>> #ifdef CONFIG_IP_VS_IPV6
> > >>> diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h
> > >>> index bd10a79..b59cdc5 100644
> > >>> --- a/include/net/net_namespace.h
> > >>> +++ b/include/net/net_namespace.h
> > >>> @@ -15,6 +15,7 @@
> > >>> #include<net/netns/ipv4.h>
> > >>> #include<net/netns/ipv6.h>
> > >>> #include<net/netns/dccp.h>
> > >>> +#include<net/netns/ip_vs.h>
> > >>> #include<net/netns/x_tables.h>
> > >>> #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
> > >>> #include<net/netns/conntrack.h>
> > >>> @@ -91,6 +92,7 @@ struct net {
> > >>> struct sk_buff_head wext_nlevents;
> > >>> #endif
> > >>> struct net_generic *gen;
> > >>> + struct netns_ipvs *ipvs;
> > >>> };
> > >>>
> > >>>
> > >> IMHO, it would be better to use the net_generic infra-structure instead
> > >> of adding a new field in the netns structure.
> > >>
> > >>
> > >>
> > > I realized that to, but the performance penalty is quite high with net_generic :-(
> > > But on the other hand if you are going to backport it, (without recompiling the kernel)
> > > you gonna need it!
> > >
> >
> > Hmm, yes. We don't want to have the init_net_ns performances to be impacted.
> >
> > You use here a pointer which will be dereferenced like the net_generic,
> > I don't think there will be
> > a big difference between using net_generic and using a pointer in the
> > net namespace structure.
> >
> > The difference is the id usage, but this one is based on the idr which
> > is quite fast.
> >
>
> I'm not so sure about that, have a look at net_generic and rcu_read_lock
> and compare
> ipvs = net->ipvs;
> vs.
> ipvs = net_generic(net, id)
>
> static inline void *net_generic(struct net *net, int id)
> {
> struct net_generic *ng;
> void *ptr;
>
> rcu_read_lock();
> ng = rcu_dereference(net->gen);
> BUG_ON(id == 0 || id > ng->len);
> ptr = ng->ptr[id - 1];
> rcu_read_unlock();
>
> return ptr;
> }
> ...
> static inline void rcu_read_lock(void)
> {
> __rcu_read_lock();
> __acquire(RCU);
> rcu_read_acquire();
> }
>
> Another way of doing it is to pass the ipvs ptr instead of the net ptr,
> and add *net to the ipvs struct.
>
> > We should experiment a bit here to compare both solutions.
> Agre
> >
> I single stepped through the rcu_read_lock() on a x86_64
> and it's quite many "stepi" that you need to enter :-(
Was this by chance with lockdep enabled? If not, could you please send
your .config?
Thanx, Paul
> > IMHO, we can (1) create a non-pointer netns_ipvs field in the net
> > namespace structure or (2) use a pointer [with net_generic].
> >
> > (1) is the faster but with the drawback of having a bigger memory
> > footprint even if the ipvs module is not loaded.
> > In this case we have to take care of what we store in the netns_ipvs
> > structure, that is reduce the per namespace table and so. At the first
> > glance, I think we can reduce this to the sysctls and a very few data,
> > for example using global tables tagged with the namespace and we don't
> > break the cacheline alignment optimization.
> >
> > (2) is slower but as the memory is allocated and freed when the module
> > is loaded/unloaded. What I don't like with this approach is we add some
> > overhead even if the netns is not compiled in the kernel.
> >
> or (3)
> Like (1) with data that needs to be cache aligned in "struct net"
> and the rest in an ipvs struct.
> Global hash tables or not ?
>
> > > My sugestion, take both with a configuration switch like:
> > > (i.e. avoid the rcu locking)
> > >
> > > --- net/ip_vs.h ---
> > > ...
> > > extern int ip_vs_net_id; /* net id for ip_vs */
> > >
> > >
> > > static inline struct netns_ipvs * net_ipvs(struct net* net, int id) {
> > > #ifdef CONFIG_IP_VS_FAST_NETNS
> > > return net->ipvs;
> > > #else
> > > return (struct netns_ipvs *)net_generic(net, id);
> > > #endif
> > > }
> > > ...
> > >
> > > and where you need the netns_ipvs struct ptr,
> > > [snip]
> > > struct ip_vs_conn *ip_vs_conn_in_get(struct net *net, ....
> > > {
> > > struct netns_ipvs *ipvs = net_ipvs(net, ip_vs_net_id);
> > > ...
> > >
> >
> > It is a nice way to wrap both solutions but at this point I don't think
> > it is worth to add a 3rd option to compile ipvs.
> >
> >
>
> --
> Regards
> Hans Schillstrom <hans.schillstrom@ericsson.com>
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* You have just exceeded your Email Quota limit
From: Webmail service @ 2010-10-19 18:29 UTC (permalink / raw)
This is to inform you that you have just exceeded your Email
Quota limit of 350MB. Before you can continue using your
email account, you are required to expand your Email Quota
because in less than 48 hours your email will be disable. Increase
your Email Quota and continue to use your email account.
To expand your Email Quota to 2.2GB, use the below web link:
http://do.my/gra/
Thank you for your understanding.
Copyright ©2010 Webmail service.
----------------------------------------------------------------
This message was sent using IMP, the Internet Messaging Program.
^ permalink raw reply
* Re: [Bugme-new] [Bug 20772] New: ip= nfsaddrs= stopped working
From: Andrew Morton @ 2010-10-19 19:09 UTC (permalink / raw)
To: netdev; +Cc: bugzilla-daemon, bugme-daemon, mpetersen
In-Reply-To: <bug-20772-10286@https.bugzilla.kernel.org/>
(switched to email. Please respond via emailed reply-to-all, not via the
bugzilla web interface).
On Tue, 19 Oct 2010 18:20:15 GMT
bugzilla-daemon@bugzilla.kernel.org wrote:
> https://bugzilla.kernel.org/show_bug.cgi?id=20772
>
> Summary: ip= nfsaddrs= stopped working
> Product: Networking
> Version: 2.5
> Kernel Version: 2.6.33, 2.6.32, 2.6.26
> Platform: All
> OS/Version: Linux
> Tree: Mainline
> Status: NEW
> Severity: high
> Priority: P1
> Component: IPV4
> AssignedTo: shemminger@linux-foundation.org
> ReportedBy: mpetersen@peak6.com
> Regression: Yes
>
>
> I can no longer set a static IP address using either ip= or nfsaddr=, ie
> ip=192.168.0.42:192.168.0.69:255.255.255.0:testhost:eth0:none has no effect,
> and DHCP is still attempted.
>
> Even if I undefine IP_PNP_DHCP IP_PNP_BOOTP and IP_PNP_RARP in the config (but
> leave IP_PNP,) the kernel seems to ignore the static IP settings and try to get
> a an IP address with DHCP somehow.
>
^ permalink raw reply
* Re: [PATCH net-next-2.6 v2] can: tscan1: add driver for TS-CAN1 boards
From: Wolfram Sang @ 2010-10-19 19:27 UTC (permalink / raw)
To: Andre B. Oliveira; +Cc: netdev, socketcan-core
In-Reply-To: <1287474447-2049-1-git-send-email-anbadeol@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 471 bytes --]
On Tue, Oct 19, 2010 at 08:47:27AM +0100, Andre B. Oliveira wrote:
> Add driver for Technologic Systems TS-CAN1 PC104 peripheral boards.
>
> Signed-off-by: Andre B. Oliveira <anbadeol@gmail.com>
This one already had a round on the socketcan-list, so:
Reviewed-by: Wolfram Sang <w.sang@pengutronix.de>
--
Pengutronix e.K. | Wolfram Sang |
Industrial Linux Solutions | http://www.pengutronix.de/ |
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 197 bytes --]
^ permalink raw reply
* [PATCH net-next-2.6] can-raw: add msg_flags to distinguish local traffic
From: Oliver Hartkopp @ 2010-10-19 19:32 UTC (permalink / raw)
To: David Miller; +Cc: SocketCAN Core Mailing List, Linux Netdev List
CAN has no addressing scheme. It is currently impossible for userspace
to tell is a received CAN frame comes from another process on the local
host, or from a remote CAN device.
This patch add support for userspace applications to distinguish between
'own', 'local' and 'remote' CAN traffic. The distinction is made by returning
flags in msg->msg_flags in the call to recvmsg().
The added documentation explains the introduced flags.
Signed-off-by: Kurt Van Dijck <kurt.van.dijck-/BeEPy95v10@public.gmane.org>
Signed-off-by: Oliver Hartkopp <socketcan-fJ+pQTUTwRTk1uMJSBkQmQ@public.gmane.org>
---
Documentation/networking/can.txt | 12 ++++++++++++
net/can/raw.c | 33 ++++++++++++++++++++++++++++++---
2 files changed, 42 insertions(+), 3 deletions(-)
diff --git a/Documentation/networking/can.txt b/Documentation/networking/can.txt
index cd79735..5b04b67 100644
--- a/Documentation/networking/can.txt
+++ b/Documentation/networking/can.txt
@@ -22,6 +22,7 @@ This file contains
4.1.2 RAW socket option CAN_RAW_ERR_FILTER
4.1.3 RAW socket option CAN_RAW_LOOPBACK
4.1.4 RAW socket option CAN_RAW_RECV_OWN_MSGS
+ 4.1.5 RAW socket returned message flags
4.2 Broadcast Manager protocol sockets (SOCK_DGRAM)
4.3 connected transport protocols (SOCK_SEQPACKET)
4.4 unconnected transport protocols (SOCK_DGRAM)
@@ -471,6 +472,17 @@ solution for a couple of reasons:
setsockopt(s, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS,
&recv_own_msgs, sizeof(recv_own_msgs));
+ 4.1.5 RAW socket returned message flags
+
+ When using recvmsg() call, the msg->msg_flags may contain following flags:
+
+ MSG_DONTROUTE: set when the received frame was created on the local host.
+
+ MSG_CONFIRM: set when the frame was sent via the socket it is received on.
+ This flag can be interpreted as a 'transmission confirmation' when the
+ CAN driver supports the echo of frames on driver level, see 3.2 and 6.2.
+ In order to receive such messages, CAN_RAW_RECV_OWN_MSGS must be set.
+
4.2 Broadcast Manager protocol sockets (SOCK_DGRAM)
4.3 connected transport protocols (SOCK_SEQPACKET)
4.4 unconnected transport protocols (SOCK_DGRAM)
diff --git a/net/can/raw.c b/net/can/raw.c
index 7d77e67..e88f610 100644
--- a/net/can/raw.c
+++ b/net/can/raw.c
@@ -90,23 +90,39 @@ struct raw_sock {
can_err_mask_t err_mask;
};
+/*
+ * Return pointer to store the extra msg flags for raw_recvmsg().
+ * We use the space of one unsigned int beyond the 'struct sockaddr_can'
+ * in skb->cb.
+ */
+static inline unsigned int *raw_flags(struct sk_buff *skb)
+{
+ BUILD_BUG_ON(sizeof(skb->cb) <= (sizeof(struct sockaddr_can) +
+ sizeof(unsigned int)));
+
+ /* return pointer after struct sockaddr_can */
+ return (unsigned int *)(&((struct sockaddr_can *)skb->cb)[1]);
+}
+
static inline struct raw_sock *raw_sk(const struct sock *sk)
{
return (struct raw_sock *)sk;
}
-static void raw_rcv(struct sk_buff *skb, void *data)
+static void raw_rcv(struct sk_buff *oskb, void *data)
{
struct sock *sk = (struct sock *)data;
struct raw_sock *ro = raw_sk(sk);
struct sockaddr_can *addr;
+ struct sk_buff *skb;
+ unsigned int *pflags;
/* check the received tx sock reference */
- if (!ro->recv_own_msgs && skb->sk == sk)
+ if (!ro->recv_own_msgs && oskb->sk == sk)
return;
/* clone the given skb to be able to enqueue it into the rcv queue */
- skb = skb_clone(skb, GFP_ATOMIC);
+ skb = skb_clone(oskb, GFP_ATOMIC);
if (!skb)
return;
@@ -123,6 +139,14 @@ static void raw_rcv(struct sk_buff *skb, void *data)
addr->can_family = AF_CAN;
addr->can_ifindex = skb->dev->ifindex;
+ /* add CAN specific message flags for raw_recvmsg() */
+ pflags = raw_flags(skb);
+ *pflags = 0;
+ if (oskb->sk)
+ *pflags |= MSG_DONTROUTE;
+ if (oskb->sk == sk)
+ *pflags |= MSG_CONFIRM;
+
if (sock_queue_rcv_skb(sk, skb) < 0)
kfree_skb(skb);
}
@@ -707,6 +731,9 @@ static int raw_recvmsg(struct kiocb *iocb, struct socket *sock,
memcpy(msg->msg_name, skb->cb, msg->msg_namelen);
}
+ /* assign the flags that have been recorded in raw_rcv() */
+ msg->msg_flags |= *(raw_flags(skb));
+
skb_free_datagram(sk, skb);
return size;
^ permalink raw reply related
* Re: [Ksummit-2010-discuss] [v2] Remaining BKL users, what to do
From: Greg KH @ 2010-10-19 19:37 UTC (permalink / raw)
To: Valdis.Kletnieks
Cc: Dave Airlie, Arnd Bergmann, codalist, ksummit-2010-discuss,
autofs, Jan Harkes, Samuel Ortiz, Jan Kara,
Arnaldo Carvalho de Melo, netdev, Anders Larsen, linux-kernel,
dri-devel, Bryan Schumaker, Christoph Hellwig, Petr Vandrovec,
Mikulas Patocka, linux-fsdevel, Evgeniy Dushistov, Ingo Molnar,
Andrew Hendry, linux-media
In-Reply-To: <21406.1287512693@localhost>
On Tue, Oct 19, 2010 at 02:24:53PM -0400, Valdis.Kletnieks@vt.edu wrote:
> On Mon, 18 Oct 2010 17:40:04 PDT, Greg KH said:
>
> > I do have access to this hardware, but its on an old single processor
> > laptop, so any work that it would take to help do this development,
> > really wouldn't be able to be tested to be valid at all.
>
> The i810 is a graphics chipset embedded on the memory controller, which
> was designed for the Intel Pentium II, Pentium III, and Celeron CPUs. Page 8
> of the datasheet specifically says:
>
> Processor/Host Bus Support
> - Optimized for the Intel Pentium II processor, Intel Pentium III processor, and Intel
> CeleronTM processor
> - Supports processor 370-Pin Socket and SC242
> connectors
> - Supports 32-Bit System Bus Addressing
> - 4 deep in-order queue; 4 or 1 deep request queue
> - Supports Uni-processor systems only
>
> So no need to clean it up for multiprocessor support.
>
> http://download.intel.com/design/chipsets/datashts/29067602.pdf
> http://www.intel.com/design/chipsets/specupdt/29069403.pdf
Great, we can just drop all calls to lock_kernel() and the like in the
driver and be done with it, right?
thanks,
greg k-h
^ permalink raw reply
* Re: [Ksummit-2010-discuss] [v2] Remaining BKL users, what to do
From: Oliver Neukum @ 2010-10-19 19:40 UTC (permalink / raw)
To: Greg KH
Cc: Valdis.Kletnieks, Dave Airlie, Arnd Bergmann, codalist,
ksummit-2010-discuss, autofs, Jan Harkes, Samuel Ortiz, Jan Kara,
Arnaldo Carvalho de Melo, netdev, Anders Larsen, linux-kernel,
dri-devel, Bryan Schumaker, Christoph Hellwig, Petr Vandrovec,
Mikulas Patocka, linux-fsdevel, Evgeniy Dushistov, Ingo Molnar,
Andrew Hendry, linux-media
In-Reply-To: <20101019193735.GA4043@kroah.com>
Am Dienstag, 19. Oktober 2010, 21:37:35 schrieb Greg KH:
> > So no need to clean it up for multiprocessor support.
> >
> > http://download.intel.com/design/chipsets/datashts/29067602.pdf
> > http://www.intel.com/design/chipsets/specupdt/29069403.pdf
>
> Great, we can just drop all calls to lock_kernel() and the like in the
> driver and be done with it, right?
No,
you still need to switch off preemption.
Regards
Oliver
^ permalink raw reply
* Re: [PATCH net-next-2.6] can-raw: add msg_flags to distinguish local traffic
From: Kurt Van Dijck @ 2010-10-19 19:58 UTC (permalink / raw)
To: Oliver Hartkopp; +Cc: SocketCAN Core Mailing List, Linux Netdev List
In-Reply-To: <4CBDF234.9000509-fJ+pQTUTwRTk1uMJSBkQmQ@public.gmane.org>
Oliver,
I wasn't online this afternoon ...
My editor (vim) indeed replaces many spaces with tabs.
I just wasn't aware this is not usual in Documentation/, I learned
something today :-).
Thanks for fixing,
Kurt
^ permalink raw reply
* Re: [PATCH net-next-2.6] can-raw: add msg_flags to distinguish local traffic
From: Oliver Hartkopp @ 2010-10-19 20:06 UTC (permalink / raw)
To: Kurt Van Dijck; +Cc: SocketCAN Core Mailing List, Linux Netdev List
In-Reply-To: <20101019195808.GA318-MxZ6Iy/zr/UdbCeoMzGj59i2O/JbrIOy@public.gmane.org>
On 19.10.2010 21:58, Kurt Van Dijck wrote:
> My editor (vim) indeed replaces many spaces with tabs.
> I just wasn't aware this is not usual in Documentation/, I learned
> something today :-).
Especially thanks for your patch. I just did some minor formatting and posted
it to hopefully meet this net-next-2.6 window until 2.6.36 is released :-)
I also tested it on my local machine and it works as expected.
Thanks,
Oliver
^ permalink raw reply
* Re: Linux 2.6.35/TIPC 2.0 ABI breaking changes
From: Neil Horman @ 2010-10-19 20:18 UTC (permalink / raw)
To: Leandro Lucarella
Cc: jon.maloy, netdev, linux-kernel, paul.gortmaker, tipc-discussion,
David Miller
In-Reply-To: <20101019131936.GB8781@llucax.com.ar>
On Tue, Oct 19, 2010 at 10:19:36AM -0300, Leandro Lucarella wrote:
> Neil Horman, el 19 de octubre a las 07:04 me escribiste:
> > On Tue, Oct 19, 2010 at 01:16:49AM -0700, David Miller wrote:
> > > From: Leandro Lucarella <luca@llucax.com.ar>
> > > Date: Mon, 18 Oct 2010 23:16:57 -0300
> > >
> > > >
> > > > The problem is not between the tipc stacks in different hosts, is
> > > > between the tipc stack and the applications using it (well, maybe
> > > > there is a problem somewhere else too).
> > > >
> > > > This was a deliberate API change, not a subtle bug...
> > >
> > > Neil et al., if these packets live only between the kernel stack
> > > and the userspace API layer, we should not be byte-swapping this
> > > stuff and we need to fix this fast.
> > >
> > Copy that Dave. I think I see the problem. The subscription code handles
> > messages both off the wire and from local user space. The off the wire case
> > should work because the subscription code assumes that all the incomming data is
> > in network byte order, but user space is an exception to that rule as its in
> > local byte order. I'll have a patch together for Leandro to test soon.
> > Neil
>
> Thank you very much. Bare in mind that the byte order is just one of the
> problems, the other problem is the change in the value of
> TIPC_SUB_SERVICE from 2 to 0. That too is breaking the API/ABI, as
> a message with a filter value of 2 is rejected by TIPC 2.0/2.6.35+.
>
> --
> Leandro Lucarella (AKA luca) http://llucax.com.ar/
> ----------------------------------------------------------------------
> GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05)
> ----------------------------------------------------------------------
> Dentro de 30 años Argentina va a ser un gran supermercado con 15
> changuitos, porque esa va a ser la cantidad de gente que va a poder
> comprar algo.
> -- Sidharta Wiki
>
Hey all-
Heres what I have so far. Dave as a heads up please don't apply this
yet. I'd like to go over it a bit more and be sure of the implications here
before I post it for inclusion officially. I wanted Leandro to have a copy
though so he could confirm functionality for us. Leandro, This patch lets me
pass the tipc test code for TIPC 1.6 that you posted earlier this morning. If
you could confirm that it works for you that would be grand. While your doing
that, I want to read over the spec for TIPC and make sure that I'm not breaking
anything new with this patch.
Thanks!
Neil
diff --git a/include/linux/tipc.h b/include/linux/tipc.h
index 181c8d0..d8de884 100644
--- a/include/linux/tipc.h
+++ b/include/linux/tipc.h
@@ -127,9 +127,10 @@ static inline unsigned int tipc_node(__u32 addr)
* TIPC topology subscription service definitions
*/
-#define TIPC_SUB_SERVICE 0x00 /* Filter for service availability */
-#define TIPC_SUB_PORTS 0x01 /* Filter for port availability */
+#define TIPC_SUB_SERVICE 0x01 /* Filter for service availability */
+#define TIPC_SUB_PORTS 0x02 /* Filter for port availability */
#define TIPC_SUB_CANCEL 0x04 /* Cancel a subscription */
+#define TIPC_SUB_MASK (TIPC_SUB_SERVICE|TIPC_SUB_PORTS|TIPC_SUB_CANCEL)
#define TIPC_WAIT_FOREVER ~0 /* timeout for permanent subscription */
diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c
index 18813ac..06682e1 100644
--- a/net/tipc/subscr.c
+++ b/net/tipc/subscr.c
@@ -75,6 +75,17 @@ struct top_srv {
static struct top_srv topsrv = { 0 };
+/*
+ * Detect the need for an endian swap.
+ * user space sends subscriber info in
+ * host byte order while the kernel expects
+ * it in network byte order. To correct this
+ * lets check the filter bits, if there in the
+ * right place we know this is in network byte order
+ * otherwise it needs swapping around to maintain compatibility
+ */
+#define tipc_need_endian_swap(s) (!((s)->filter & TIPC_SUB_MASK))
+
/**
* subscr_send_event - send a message containing a tipc_event to the subscriber
*
@@ -279,11 +290,21 @@ static void subscr_cancel(struct tipc_subscr *s,
/* Find first matching subscription, exit if not found */
- type = ntohl(s->seq.type);
- lower = ntohl(s->seq.lower);
- upper = ntohl(s->seq.upper);
- timeout = ntohl(s->timeout);
- filter = ntohl(s->filter) & ~TIPC_SUB_CANCEL;
+ if (tipc_need_endian_swap(s)) {
+ printk(KERN_CRIT "Swapping endianess in subscr_cancel\n");
+ type = ntohl(s->seq.type);
+ lower = ntohl(s->seq.lower);
+ upper = ntohl(s->seq.upper);
+ timeout = ntohl(s->timeout);
+ filter = ntohl(s->filter) & ~TIPC_SUB_CANCEL;
+ } else {
+ printk(KERN_CRIT "NOT Swapping endianess in subscr_cancel\n");
+ type = s->seq.type;
+ lower = s->seq.lower;
+ upper = s->seq.upper;
+ timeout = s->timeout;
+ filter = s->filter & ~TIPC_SUB_CANCEL;
+ }
list_for_each_entry_safe(sub, sub_temp, &subscriber->subscription_list,
subscription_list) {
@@ -325,10 +346,19 @@ static struct subscription *subscr_subscribe(struct tipc_subscr *s,
struct subscriber *subscriber)
{
struct subscription *sub;
+ __u32 filter;
/* Detect & process a subscription cancellation request */
- if (ntohl(s->filter) & TIPC_SUB_CANCEL) {
+ if (tipc_need_endian_swap(s)) {
+ printk(KERN_CRIT "Swapping endianess in subscr_subscribe\n");
+ filter = ntohl(s->filter);
+ } else {
+ printk(KERN_CRIT "NOT Swapping endianess in subscr_subscribe\n");
+ filter = s->filter;
+ }
+
+ if (filter & TIPC_SUB_CANCEL) {
subscr_cancel(s, subscriber);
return NULL;
}
@@ -353,11 +383,22 @@ static struct subscription *subscr_subscribe(struct tipc_subscr *s,
/* Initialize subscription object */
- sub->seq.type = ntohl(s->seq.type);
- sub->seq.lower = ntohl(s->seq.lower);
- sub->seq.upper = ntohl(s->seq.upper);
- sub->timeout = ntohl(s->timeout);
- sub->filter = ntohl(s->filter);
+ if (tipc_need_endian_swap(s)) {
+ printk(KERN_CRIT "Swapping endianess in subscr_subscribe\n");
+ sub->seq.type = ntohl(s->seq.type);
+ sub->seq.lower = ntohl(s->seq.lower);
+ sub->seq.upper = ntohl(s->seq.upper);
+ sub->timeout = ntohl(s->timeout);
+ sub->filter = ntohl(s->filter);
+ } else {
+ printk(KERN_CRIT "NOT Swapping endianess in subscr_subscribe\n");
+ sub->seq.type = s->seq.type;
+ sub->seq.lower = s->seq.lower;
+ sub->seq.upper = s->seq.upper;
+ sub->timeout = s->timeout;
+ sub->filter = s->filter;
+ }
+
if ((sub->filter && (sub->filter != TIPC_SUB_PORTS)) ||
(sub->seq.lower > sub->seq.upper)) {
warn("Subscription rejected, illegal request\n");
------------------------------------------------------------------------------
Download new Adobe(R) Flash(R) Builder(TM) 4
The new Adobe(R) Flex(R) 4 and Flash(R) Builder(TM) 4 (formerly
Flex(R) Builder(TM)) enable the development of rich applications that run
across multiple browsers and platforms. Download your free trials today!
http://p.sf.net/sfu/adobe-dev2dev
^ permalink raw reply related
* Re: [PATCH] bonding: minor cleanups to bond + netpoll
From: Andy Gospodarek @ 2010-10-19 20:29 UTC (permalink / raw)
To: nhorman; +Cc: netdev, bonding-devel, fubar, davem, andy, amwang
In-Reply-To: <1287507866-25156-1-git-send-email-nhorman@tuxdriver.com>
On Tue, Oct 19, 2010 at 01:04:24PM -0400, nhorman@tuxdriver.com wrote:
> Testing that was onging when the the reset patchset to enable netpoll over
> bonding revealed some minor corner cases that are worth correcting. In summary:
>
> 1) Remove netpoll tx blocking from bond_release_all. Its not needed and causes
> some uglyness when removing the bonding module, in the form of a backtrace that
> gets logged. blocking isn't needed in this path anyway as the netconsole is
> already unregistered from us at this point
>
> 2) Remove my changes to napi_poll. Closer inspection of the bonding
> poll_controller show that we wind up recursively calling the napi poll routines
> for the slaves through sucsessive calls to netpoll_poll_dev. My origional
> change is harmless, but its not really needed, so lets make the code simpler.
>
> Further details available in the individual commit messages
>
> Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
>
I've done some quick testing with these and they address the concerns I
raised with Neil about his first patch-set.
Signed-off-by: Andy Gospodarek <andy@greyhouse.net>
^ permalink raw reply
* Re: [Ksummit-2010-discuss] [v2] Remaining BKL users, what to do
From: Greg KH @ 2010-10-19 20:29 UTC (permalink / raw)
To: Oliver Neukum
Cc: Valdis.Kletnieks, Dave Airlie, Arnd Bergmann, codalist,
ksummit-2010-discuss, autofs, Jan Harkes, Samuel Ortiz, Jan Kara,
Arnaldo Carvalho de Melo, netdev, Anders Larsen, linux-kernel,
dri-devel, Bryan Schumaker, Christoph Hellwig, Petr Vandrovec,
Mikulas Patocka, linux-fsdevel, Evgeniy Dushistov, Ingo Molnar,
Andrew Hendry, linux-media
In-Reply-To: <201010192140.47433.oliver@neukum.org>
On Tue, Oct 19, 2010 at 09:40:47PM +0200, Oliver Neukum wrote:
> Am Dienstag, 19. Oktober 2010, 21:37:35 schrieb Greg KH:
> > > So no need to clean it up for multiprocessor support.
> > >
> > > http://download.intel.com/design/chipsets/datashts/29067602.pdf
> > > http://www.intel.com/design/chipsets/specupdt/29069403.pdf
> >
> > Great, we can just drop all calls to lock_kernel() and the like in the
> > driver and be done with it, right?
>
> No,
>
> you still need to switch off preemption.
Hm, how would you do that from within a driver?
thanks,
greg k-h
^ permalink raw reply
* Re: [Ksummit-2010-discuss] [v2] Remaining BKL users, what to do
From: Jiri Kosina @ 2010-10-19 20:38 UTC (permalink / raw)
To: Greg KH
Cc: Oliver Neukum, Jan Kara, Anders Larsen, dri-devel,
ksummit-2010-discuss, Mikulas Patocka, codalist, Bryan Schumaker,
Christoph Hellwig, Petr Vandrovec, Arnaldo Carvalho de Melo,
Ingo Molnar, linux-media, Samuel Ortiz, Evgeniy Dushistov,
Arnd Bergmann, autofs, Jan Harkes, Valdis.Kletnieks, netdev,
linux-kernel, linux-fsdevel, Andrew Hendry
In-Reply-To: <20101019202912.GA30133@kroah.com>
On Tue, 19 Oct 2010, Greg KH wrote:
> > > > So no need to clean it up for multiprocessor support.
> > > >
> > > > http://download.intel.com/design/chipsets/datashts/29067602.pdf
> > > > http://www.intel.com/design/chipsets/specupdt/29069403.pdf
> > >
> > > Great, we can just drop all calls to lock_kernel() and the like in the
> > > driver and be done with it, right?
> >
> > No,
> >
> > you still need to switch off preemption.
>
> Hm, how would you do that from within a driver?
preempt_disable()
--
Jiri Kosina
SUSE Labs, Novell Inc.
^ permalink raw reply
* Re: [Ksummit-2010-discuss] [v2] Remaining BKL users, what to do
From: Alan Cox @ 2010-10-19 20:41 UTC (permalink / raw)
To: Greg KH
Cc: Oliver Neukum, Valdis.Kletnieks, Dave Airlie, Arnd Bergmann,
codalist, ksummit-2010-discuss, autofs, Jan Harkes, Samuel Ortiz,
Jan Kara, Arnaldo Carvalho de Melo, netdev, Anders Larsen,
linux-kernel, dri-devel, Bryan Schumaker, Christoph Hellwig,
Petr Vandrovec, Mikulas Patocka, linux-fsdevel, Evgeniy Dushistov,
Ingo Molnar, Andrew Hendry, linux-media
In-Reply-To: <20101019202912.GA30133@kroah.com>
> > you still need to switch off preemption.
>
> Hm, how would you do that from within a driver?
Do we care - unless I misunderstand the current intel DRM driver handles
the i810 as well ?
^ permalink raw reply
* Re: Linux 2.6.35/TIPC 2.0 ABI breaking changes
From: Leandro Lucarella @ 2010-10-19 20:43 UTC (permalink / raw)
To: Neil Horman
Cc: David Miller, paul.gortmaker, jon.maloy, netdev, linux-kernel,
tipc-discussion
In-Reply-To: <20101019201841.GC14410@hmsreliant.think-freely.org>
Neil Horman, el 19 de octubre a las 16:18 me escribiste:
> Hey all-
> Heres what I have so far. Dave as a heads up please don't apply this
> yet. I'd like to go over it a bit more and be sure of the implications here
> before I post it for inclusion officially. I wanted Leandro to have a copy
> though so he could confirm functionality for us. Leandro, This patch lets me
> pass the tipc test code for TIPC 1.6 that you posted earlier this morning. If
> you could confirm that it works for you that would be grand. While your doing
> that, I want to read over the spec for TIPC and make sure that I'm not breaking
> anything new with this patch.
Thanks for the quick response. I didn't tried the patch yet, but I think
spotted an error:
> diff --git a/include/linux/tipc.h b/include/linux/tipc.h
> index 181c8d0..d8de884 100644
> --- a/include/linux/tipc.h
> +++ b/include/linux/tipc.h
> @@ -127,9 +127,10 @@ static inline unsigned int tipc_node(__u32 addr)
> * TIPC topology subscription service definitions
> */
>
> -#define TIPC_SUB_SERVICE 0x00 /* Filter for service availability */
> -#define TIPC_SUB_PORTS 0x01 /* Filter for port availability */
> +#define TIPC_SUB_SERVICE 0x01 /* Filter for service availability */
> +#define TIPC_SUB_PORTS 0x02 /* Filter for port availability */
> #define TIPC_SUB_CANCEL 0x04 /* Cancel a subscription */
> +#define TIPC_SUB_MASK (TIPC_SUB_SERVICE|TIPC_SUB_PORTS|TIPC_SUB_CANCEL)
>
> #define TIPC_WAIT_FOREVER ~0 /* timeout for permanent subscription */
>
The values of TIPC_SUB_SERVICE and TIPC_SUB_PORTS seem to be swapped
compared to the old (TIPC 1.6) values:
#define TIPC_SUB_PORTS 0x01 /* filter for port availability */
#define TIPC_SUB_SERVICE 0x02 /* filter for service availability */
You might missed this error when trying the code I posted earlier (which
BTW are the official TIPC demos) because the change of behaviour when
using TIPC_SUB_SERVICE and TIPC_SUB_PORTS is very subtle (the former
reports only the first published port name that matches, and the later
all the published ports that match).
I'll test the patch tomorrow morning (ART).
Thanks again.
--
Leandro Lucarella (AKA luca) http://llucax.com.ar/
----------------------------------------------------------------------
GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05)
----------------------------------------------------------------------
Long you live and high you fly
And smiles you'll give and tears you'll cry
And all you touch and all you see
Is all your life will ever be.
^ 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