From 0e5a117441ce245b87949cc7713627a293f37227 Mon Sep 17 00:00:00 2001 From: "sjur.brandeland@stericsson.com" Date: Sun, 22 May 2011 11:18:50 +0000 Subject: caif: Bugfix add check NULL pointer before calling functions. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add check on layer->dn != NULL before calling functions in layer below. Signed-off-by: Sjur Brændeland Signed-off-by: David S. Miller diff --git a/net/caif/cfctrl.c b/net/caif/cfctrl.c index 0c00a60..f8ac313 100644 --- a/net/caif/cfctrl.c +++ b/net/caif/cfctrl.c @@ -178,20 +178,23 @@ static void init_info(struct caif_payload_info *info, struct cfctrl *cfctrl) void cfctrl_enum_req(struct cflayer *layer, u8 physlinkid) { struct cfctrl *cfctrl = container_obj(layer); - int ret; struct cfpkt *pkt = cfpkt_create(CFPKT_CTRL_PKT_LEN); + struct cflayer *dn = cfctrl->serv.layer.dn; if (!pkt) { pr_warn("Out of memory\n"); return; } + if (!dn) { + pr_debug("not able to send enum request\n"); + return; + } caif_assert(offsetof(struct cfctrl, serv.layer) == 0); init_info(cfpkt_info(pkt), cfctrl); cfpkt_info(pkt)->dev_info->id = physlinkid; cfctrl->serv.dev_info.id = physlinkid; cfpkt_addbdy(pkt, CFCTRL_CMD_ENUM); cfpkt_addbdy(pkt, physlinkid); - ret = - cfctrl->serv.layer.dn->transmit(cfctrl->serv.layer.dn, pkt); + dn->transmit(dn, pkt); } int cfctrl_linkup_request(struct cflayer *layer, @@ -206,6 +209,12 @@ int cfctrl_linkup_request(struct cflayer *layer, int ret; char utility_name[16]; struct cfpkt *pkt; + struct cflayer *dn = cfctrl->serv.layer.dn; + + if (!dn) { + pr_debug("not able to send linkup request\n"); + return -ENODEV; + } if (cfctrl_cancel_req(layer, user_layer) > 0) { /* Slight Paranoia, check if already connecting */ @@ -282,7 +291,7 @@ int cfctrl_linkup_request(struct cflayer *layer, */ cfpkt_info(pkt)->dev_info->id = param->phyid; ret = - cfctrl->serv.layer.dn->transmit(cfctrl->serv.layer.dn, pkt); + dn->transmit(dn, pkt); if (ret < 0) { int count; @@ -301,15 +310,23 @@ int cfctrl_linkdown_req(struct cflayer *layer, u8 channelid, int ret; struct cfctrl *cfctrl = container_obj(layer); struct cfpkt *pkt = cfpkt_create(CFPKT_CTRL_PKT_LEN); + struct cflayer *dn = cfctrl->serv.layer.dn; + if (!pkt) { pr_warn("Out of memory\n"); return -ENOMEM; } + + if (!dn) { + pr_debug("not able to send link-down request\n"); + return -ENODEV; + } + cfpkt_addbdy(pkt, CFCTRL_CMD_LINK_DESTROY); cfpkt_addbdy(pkt, channelid); init_info(cfpkt_info(pkt), cfctrl); ret = - cfctrl->serv.layer.dn->transmit(cfctrl->serv.layer.dn, pkt); + dn->transmit(dn, pkt); #ifndef CAIF_NO_LOOP cfctrl->loop_linkused[channelid] = 0; #endif @@ -477,7 +494,7 @@ static int cfctrl_recv(struct cflayer *layer, struct cfpkt *pkt) cfpkt_extr_head(pkt, ¶m, len); break; default: - pr_warn("Request setup - invalid link type (%d)\n", + pr_warn("Request setup, invalid type (%d)\n", serv); goto error; } @@ -489,7 +506,8 @@ static int cfctrl_recv(struct cflayer *layer, struct cfpkt *pkt) if (CFCTRL_ERR_BIT == (CFCTRL_ERR_BIT & cmdrsp) || cfpkt_erroneous(pkt)) { - pr_err("Invalid O/E bit or parse error on CAIF control channel\n"); + pr_err("Invalid O/E bit or parse error " + "on CAIF control channel\n"); cfctrl->res.reject_rsp(cfctrl->serv.layer.up, 0, req ? req->client_layer @@ -550,9 +568,8 @@ static void cfctrl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl, case _CAIF_CTRLCMD_PHYIF_FLOW_OFF_IND: case CAIF_CTRLCMD_FLOW_OFF_IND: spin_lock_bh(&this->info_list_lock); - if (!list_empty(&this->list)) { + if (!list_empty(&this->list)) pr_debug("Received flow off in control layer\n"); - } spin_unlock_bh(&this->info_list_lock); break; case _CAIF_CTRLCMD_PHYIF_DOWN_IND: { -- cgit v0.10.2 From 54e90fb5ca8050156d3e748ddc690ed6ea9d71ac Mon Sep 17 00:00:00 2001 From: "sjur.brandeland@stericsson.com" Date: Sun, 22 May 2011 11:18:51 +0000 Subject: caif: Fixes freeze on Link layer removal. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CAIF Socket layer - caif_socket.c: - Plug mem-leak at reconnect. - Always call disconnect to cleanup CAIF stack. - Disconnect will always report success. CAIF configuration layer - cfcnfg.c - Disconnect must dismantle the caif stack correctly - Protect against faulty removals (check on id zero) CAIF mux layer - cfmuxl.c - When inserting new service layer in the MUX remove any old entries with the same ID. - When removing CAIF Link layer, remove the associated service layers before notifying service layers. Signed-off-by: Sjur Brændeland Signed-off-by: David S. Miller diff --git a/net/caif/caif_socket.c b/net/caif/caif_socket.c index b840395..a986280 100644 --- a/net/caif/caif_socket.c +++ b/net/caif/caif_socket.c @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include #include #include @@ -816,6 +816,7 @@ static int caif_connect(struct socket *sock, struct sockaddr *uaddr, if (sk->sk_shutdown & SHUTDOWN_MASK) { /* Allow re-connect after SHUTDOWN_IND */ caif_disconnect_client(sock_net(sk), &cf_sk->layer); + caif_free_client(&cf_sk->layer); break; } /* No reconnect on a seqpacket socket */ @@ -926,7 +927,6 @@ static int caif_release(struct socket *sock) { struct sock *sk = sock->sk; struct caifsock *cf_sk = container_of(sk, struct caifsock, sk); - int res = 0; if (!sk) return 0; @@ -953,10 +953,7 @@ static int caif_release(struct socket *sock) sk->sk_state = CAIF_DISCONNECTED; sk->sk_shutdown = SHUTDOWN_MASK; - if (cf_sk->sk.sk_socket->state == SS_CONNECTED || - cf_sk->sk.sk_socket->state == SS_CONNECTING) - res = caif_disconnect_client(sock_net(sk), &cf_sk->layer); - + caif_disconnect_client(sock_net(sk), &cf_sk->layer); cf_sk->sk.sk_socket->state = SS_DISCONNECTING; wake_up_interruptible_poll(sk_sleep(sk), POLLERR|POLLHUP); @@ -964,7 +961,7 @@ static int caif_release(struct socket *sock) sk_stream_kill_queues(&cf_sk->sk); release_sock(sk); sock_put(sk); - return res; + return 0; } /* Copied from af_unix.c:unix_poll(), added CAIF tx_flow handling */ @@ -1120,7 +1117,7 @@ static int caif_create(struct net *net, struct socket *sock, int protocol, set_rx_flow_on(cf_sk); /* Set default options on configuration */ - cf_sk->sk.sk_priority= CAIF_PRIO_NORMAL; + cf_sk->sk.sk_priority = CAIF_PRIO_NORMAL; cf_sk->conn_req.link_selector = CAIF_LINK_LOW_LATENCY; cf_sk->conn_req.protocol = protocol; /* Increase the number of sockets created. */ diff --git a/net/caif/cfcnfg.c b/net/caif/cfcnfg.c index 351c2ca..52fe33b 100644 --- a/net/caif/cfcnfg.c +++ b/net/caif/cfcnfg.c @@ -182,39 +182,26 @@ static int cfcnfg_get_id_from_ifi(struct cfcnfg *cnfg, int ifi) int caif_disconnect_client(struct net *net, struct cflayer *adap_layer) { - u8 channel_id = 0; - int ret = 0; - struct cflayer *servl = NULL; + u8 channel_id; struct cfcnfg *cfg = get_cfcnfg(net); caif_assert(adap_layer != NULL); - - channel_id = adap_layer->id; - if (adap_layer->dn == NULL || channel_id == 0) { - pr_err("adap_layer->dn == NULL or adap_layer->id is 0\n"); - ret = -ENOTCONN; - goto end; - } - - servl = cfmuxl_remove_uplayer(cfg->mux, channel_id); - if (servl == NULL) { - pr_err("PROTOCOL ERROR - " - "Error removing service_layer Channel_Id(%d)", - channel_id); - ret = -EINVAL; - goto end; - } - - ret = cfctrl_linkdown_req(cfg->ctrl, channel_id, adap_layer); - -end: cfctrl_cancel_req(cfg->ctrl, adap_layer); + channel_id = adap_layer->id; + if (channel_id != 0) { + struct cflayer *servl; + servl = cfmuxl_remove_uplayer(cfg->mux, channel_id); + if (servl != NULL) + layer_set_up(servl, NULL); + } else + pr_debug("nothing to disconnect\n"); + cfctrl_linkdown_req(cfg->ctrl, channel_id, adap_layer); /* Do RCU sync before initiating cleanup */ synchronize_rcu(); if (adap_layer->ctrlcmd != NULL) adap_layer->ctrlcmd(adap_layer, CAIF_CTRLCMD_DEINIT_RSP, 0); - return ret; + return 0; } EXPORT_SYMBOL(caif_disconnect_client); @@ -400,6 +387,14 @@ cfcnfg_linkup_rsp(struct cflayer *layer, u8 channel_id, enum cfctrl_srv serv, struct cfcnfg_phyinfo *phyinfo; struct net_device *netdev; + if (channel_id == 0) { + pr_warn("received channel_id zero\n"); + if (adapt_layer != NULL && adapt_layer->ctrlcmd != NULL) + adapt_layer->ctrlcmd(adapt_layer, + CAIF_CTRLCMD_INIT_FAIL_RSP, 0); + return; + } + rcu_read_lock(); if (adapt_layer == NULL) { @@ -523,7 +518,6 @@ got_phyid: phyinfo->use_stx = stx; phyinfo->use_fcs = fcs; - phy_layer->type = phy_type; frml = cffrml_create(phyid, fcs); if (!frml) { diff --git a/net/caif/cfmuxl.c b/net/caif/cfmuxl.c index 2a56df7..3a66b8c 100644 --- a/net/caif/cfmuxl.c +++ b/net/caif/cfmuxl.c @@ -62,16 +62,6 @@ struct cflayer *cfmuxl_create(void) return &this->layer; } -int cfmuxl_set_uplayer(struct cflayer *layr, struct cflayer *up, u8 linkid) -{ - struct cfmuxl *muxl = container_obj(layr); - - spin_lock_bh(&muxl->receive_lock); - list_add_rcu(&up->node, &muxl->srvl_list); - spin_unlock_bh(&muxl->receive_lock); - return 0; -} - int cfmuxl_set_dnlayer(struct cflayer *layr, struct cflayer *dn, u8 phyid) { struct cfmuxl *muxl = (struct cfmuxl *) layr; @@ -93,6 +83,24 @@ static struct cflayer *get_from_id(struct list_head *list, u16 id) return NULL; } +int cfmuxl_set_uplayer(struct cflayer *layr, struct cflayer *up, u8 linkid) +{ + struct cfmuxl *muxl = container_obj(layr); + struct cflayer *old; + + spin_lock_bh(&muxl->receive_lock); + + /* Two entries with same id is wrong, so remove old layer from mux */ + old = get_from_id(&muxl->srvl_list, linkid); + if (old != NULL) + list_del_rcu(&old->node); + + list_add_rcu(&up->node, &muxl->srvl_list); + spin_unlock_bh(&muxl->receive_lock); + + return 0; +} + struct cflayer *cfmuxl_remove_dnlayer(struct cflayer *layr, u8 phyid) { struct cfmuxl *muxl = container_obj(layr); @@ -146,6 +154,11 @@ struct cflayer *cfmuxl_remove_uplayer(struct cflayer *layr, u8 id) struct cfmuxl *muxl = container_obj(layr); int idx = id % UP_CACHE_SIZE; + if (id == 0) { + pr_warn("Trying to remove control layer\n"); + return NULL; + } + spin_lock_bh(&muxl->receive_lock); up = get_from_id(&muxl->srvl_list, id); if (up == NULL) @@ -235,12 +248,26 @@ static void cfmuxl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl, { struct cfmuxl *muxl = container_obj(layr); struct cflayer *layer; + int idx; rcu_read_lock(); list_for_each_entry_rcu(layer, &muxl->srvl_list, node) { - if (cfsrvl_phyid_match(layer, phyid) && layer->ctrlcmd) + + if (cfsrvl_phyid_match(layer, phyid) && layer->ctrlcmd) { + + if ((ctrl == _CAIF_CTRLCMD_PHYIF_FLOW_OFF_IND || + ctrl == CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND) && + layer->id != 0) { + + idx = layer->id % UP_CACHE_SIZE; + spin_lock_bh(&muxl->receive_lock); + rcu_assign_pointer(muxl->up_cache[idx], NULL); + list_del_rcu(&layer->node); + spin_unlock_bh(&muxl->receive_lock); + } /* NOTE: ctrlcmd is not allowed to block */ layer->ctrlcmd(layer, ctrl, phyid); + } } rcu_read_unlock(); } -- cgit v0.10.2 From 96796ea8b6b1221c7cacf68ce056d77eff0a793d Mon Sep 17 00:00:00 2001 From: "sjur.brandeland@stericsson.com" Date: Sun, 22 May 2011 11:18:52 +0000 Subject: caif: Fix freezes when running CAIF loopback device MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix spinlock bugs when running out of link-ids in loopback tests and avoid allocating link-id when error is set in link-setup-response. Signed-off-by: Sjur Brændeland Signed-off-by: David S. Miller diff --git a/net/caif/cfctrl.c b/net/caif/cfctrl.c index f8ac313..e22671b 100644 --- a/net/caif/cfctrl.c +++ b/net/caif/cfctrl.c @@ -368,7 +368,8 @@ static int cfctrl_recv(struct cflayer *layer, struct cfpkt *pkt) cfpkt_extr_head(pkt, &cmdrsp, 1); cmd = cmdrsp & CFCTRL_CMD_MASK; if (cmd != CFCTRL_CMD_LINK_ERR - && CFCTRL_RSP_BIT != (CFCTRL_RSP_BIT & cmdrsp)) { + && CFCTRL_RSP_BIT != (CFCTRL_RSP_BIT & cmdrsp) + && CFCTRL_ERR_BIT != (CFCTRL_ERR_BIT & cmdrsp)) { if (handle_loop(cfctrl, cmd, pkt) != 0) cmdrsp |= CFCTRL_ERR_BIT; } @@ -604,16 +605,16 @@ static int handle_loop(struct cfctrl *ctrl, int cmd, struct cfpkt *pkt) case CFCTRL_CMD_LINK_SETUP: spin_lock_bh(&ctrl->loop_linkid_lock); if (!dec) { - for (linkid = last_linkid + 1; linkid < 255; linkid++) + for (linkid = last_linkid + 1; linkid < 254; linkid++) if (!ctrl->loop_linkused[linkid]) goto found; } dec = 1; - for (linkid = last_linkid - 1; linkid > 0; linkid--) + for (linkid = last_linkid - 1; linkid > 1; linkid--) if (!ctrl->loop_linkused[linkid]) goto found; spin_unlock_bh(&ctrl->loop_linkid_lock); - + return -1; found: if (linkid < 10) dec = 0; -- cgit v0.10.2 From 138eded8ba1227261a297b32b7940664c14d193e Mon Sep 17 00:00:00 2001 From: "sjur.brandeland@stericsson.com" Date: Sun, 22 May 2011 11:18:53 +0000 Subject: caif: Update documentation of CAIF transmit and receive functions. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Trivial patch updating documentation in header files only. Error handling of CAIF transmit errors was changed by commit: caif: Don't resend if dev_queue_xmit fails. This patch updates the documentation accordingly. Signed-off-by: Sjur Brændeland Signed-off-by: David S. Miller diff --git a/include/net/caif/caif_layer.h b/include/net/caif/caif_layer.h index c8b07a9..35bc788 100644 --- a/include/net/caif/caif_layer.h +++ b/include/net/caif/caif_layer.h @@ -15,7 +15,6 @@ struct cfpktq; struct caif_payload_info; struct caif_packet_funcs; - #define CAIF_LAYER_NAME_SZ 16 /** @@ -33,7 +32,6 @@ do { \ } \ } while (0) - /** * enum caif_ctrlcmd - CAIF Stack Control Signaling sent in layer.ctrlcmd(). * @@ -141,7 +139,7 @@ enum caif_direction { * - All layers must use this structure. If embedding it, then place this * structure first in the layer specific structure. * - * - Each layer should not depend on any others layer private data. + * - Each layer should not depend on any others layer's private data. * * - In order to send data upwards do * layer->up->receive(layer->up, packet); @@ -155,16 +153,23 @@ struct cflayer { struct list_head node; /* - * receive() - Receive Function. + * receive() - Receive Function (non-blocking). * Contract: Each layer must implement a receive function passing the * CAIF packets upwards in the stack. * Packet handling rules: - * - The CAIF packet (cfpkt) cannot be accessed after - * passing it to the next layer using up->receive(). + * - The CAIF packet (cfpkt) ownership is passed to the + * called receive function. This means that the the + * packet cannot be accessed after passing it to the + * above layer using up->receive(). + * * - If parsing of the packet fails, the packet must be - * destroyed and -1 returned from the function. + * destroyed and negative error code returned + * from the function. + * EXCEPTION: If the framing layer (cffrml) returns + * -EILSEQ, the packet is not freed. + * * - If parsing succeeds (and above layers return OK) then - * the function must return a value > 0. + * the function must return a value >= 0. * * Returns result < 0 indicates an error, 0 or positive value * indicates success. @@ -176,7 +181,7 @@ struct cflayer { int (*receive)(struct cflayer *layr, struct cfpkt *cfpkt); /* - * transmit() - Transmit Function. + * transmit() - Transmit Function (non-blocking). * Contract: Each layer must implement a transmit function passing the * CAIF packet downwards in the stack. * Packet handling rules: @@ -185,15 +190,16 @@ struct cflayer { * cannot be accessed after passing it to the below * layer using dn->transmit(). * - * - If transmit fails, however, the ownership is returned - * to thecaller. The caller of "dn->transmit()" must - * destroy or resend packet. + * - Upon error the packet ownership is still passed on, + * so the packet shall be freed where error is detected. + * Callers of the transmit function shall not free packets, + * but errors shall be returned. * * - Return value less than zero means error, zero or * greater than zero means OK. * - * result < 0 indicates an error, 0 or positive value - * indicate success. + * Returns result < 0 indicates an error, 0 or positive value + * indicates success. * * @layr: Pointer to the current layer the receive function * isimplemented for (this pointer). @@ -202,7 +208,7 @@ struct cflayer { int (*transmit) (struct cflayer *layr, struct cfpkt *cfpkt); /* - * cttrlcmd() - Control Function upwards in CAIF Stack. + * cttrlcmd() - Control Function upwards in CAIF Stack (non-blocking). * Used for signaling responses (CAIF_CTRLCMD_*_RSP) * and asynchronous events from the modem (CAIF_CTRLCMD_*_IND) * -- cgit v0.10.2 From 69c867c90c7fe0773d9aa4e8bbf777f574be13d2 Mon Sep 17 00:00:00 2001 From: "sjur.brandeland@stericsson.com" Date: Sun, 22 May 2011 11:18:54 +0000 Subject: caif: Plug memory leak for checksum error MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In case of checksum error, the framing layer returns -EILSEQ, but does not free the packet. Plug this hole by freeing the packet if -EILSEQ is returned. Signed-off-by: Sjur Brændeland Signed-off-by: David S. Miller diff --git a/net/caif/caif_dev.c b/net/caif/caif_dev.c index 366ca0f..682c0fe 100644 --- a/net/caif/caif_dev.c +++ b/net/caif/caif_dev.c @@ -142,6 +142,7 @@ static int receive(struct sk_buff *skb, struct net_device *dev, { struct cfpkt *pkt; struct caif_device_entry *caifd; + int err; pkt = cfpkt_fromnative(CAIF_DIR_IN, skb); @@ -159,7 +160,11 @@ static int receive(struct sk_buff *skb, struct net_device *dev, caifd_hold(caifd); rcu_read_unlock(); - caifd->layer.up->receive(caifd->layer.up, pkt); + err = caifd->layer.up->receive(caifd->layer.up, pkt); + + /* For -EILSEQ the packet is not freed so so it now */ + if (err == -EILSEQ) + cfpkt_destroy(pkt); /* Release reference to stack upwards */ caifd_put(caifd); -- cgit v0.10.2 From 0fcbe742eaac14bd5032b369c09e9d94be9058ad Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 22 May 2011 20:35:29 -0400 Subject: net: Remove prefetches from SKB list handlers. Noticed by Linus. Signed-off-by: David S. Miller diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 8276815..09901fd 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -1783,7 +1783,7 @@ static inline int pskb_trim_rcsum(struct sk_buff *skb, unsigned int len) #define skb_queue_walk(queue, skb) \ for (skb = (queue)->next; \ - prefetch(skb->next), (skb != (struct sk_buff *)(queue)); \ + (skb != (struct sk_buff *)(queue)); \ skb = skb->next) #define skb_queue_walk_safe(queue, skb, tmp) \ @@ -1792,7 +1792,7 @@ static inline int pskb_trim_rcsum(struct sk_buff *skb, unsigned int len) skb = tmp, tmp = skb->next) #define skb_queue_walk_from(queue, skb) \ - for (; prefetch(skb->next), (skb != (struct sk_buff *)(queue)); \ + for (; (skb != (struct sk_buff *)(queue)); \ skb = skb->next) #define skb_queue_walk_from_safe(queue, skb, tmp) \ @@ -1802,7 +1802,7 @@ static inline int pskb_trim_rcsum(struct sk_buff *skb, unsigned int len) #define skb_queue_reverse_walk(queue, skb) \ for (skb = (queue)->prev; \ - prefetch(skb->prev), (skb != (struct sk_buff *)(queue)); \ + (skb != (struct sk_buff *)(queue)); \ skb = skb->prev) #define skb_queue_reverse_walk_safe(queue, skb, tmp) \ -- cgit v0.10.2 From 8df8a47538ac2e26f07efabc8793c06e96a35226 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 22 May 2011 20:35:54 -0400 Subject: rionet: Remove pointless printk of skb pointer. Casting to u32 warns anyways. Signed-off-by: David S. Miller diff --git a/drivers/net/rionet.c b/drivers/net/rionet.c index 26afbaa..77c5092 100644 --- a/drivers/net/rionet.c +++ b/drivers/net/rionet.c @@ -162,8 +162,8 @@ static int rionet_queue_tx_msg(struct sk_buff *skb, struct net_device *ndev, rnet->tx_slot &= (RIONET_TX_RING_SIZE - 1); if (netif_msg_tx_queued(rnet)) - printk(KERN_INFO "%s: queued skb %8.8x len %8.8x\n", DRV_NAME, - (u32) skb, skb->len); + printk(KERN_INFO "%s: queued skb len %8.8x\n", DRV_NAME, + skb->len); return 0; } -- cgit v0.10.2 From c0cba59e77b5640912a331566bbfa66ae5029f37 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Sun, 22 May 2011 11:02:08 +0000 Subject: drivers/net: add prefetch header for prefetch users After discovering that wide use of prefetch on modern CPUs could be a net loss instead of a win, net drivers which were relying on the implicit inclusion of prefetch.h via the list headers showed up in the resulting cleanup fallout. Give them an explicit include via the following $0.02 script. ========================================= #!/bin/bash MANUAL="" for i in `git grep -l 'prefetch(.*)' .` ; do grep -q '' $i if [ $? = 0 ] ; then continue fi ( echo '?^#include ' echo . echo w echo q ) | ed -s $i > /dev/null 2>&1 if [ $? != 0 ]; then echo $i needs manual fixup MANUAL="$i $MANUAL" fi done echo ------------------- 8\<---------------------- echo vi $MANUAL ========================================= Signed-off-by: Paul Signed-off-by: David S. Miller diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 4b5e0ed..a485f7f 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -15,6 +15,7 @@ * Costa Mesa, CA 92626 */ +#include #include "be.h" #include "be_cmds.h" #include diff --git a/drivers/net/bna/bnad.c b/drivers/net/bna/bnad.c index e588511..7d25a97 100644 --- a/drivers/net/bna/bnad.c +++ b/drivers/net/bna/bnad.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "bnad.h" #include "bna.h" diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index ca2bbc0..64d01e7 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "bnx2x_cmn.h" #include "bnx2x_init.h" diff --git a/drivers/net/chelsio/sge.c b/drivers/net/chelsio/sge.c index b948ea7..58380d2 100644 --- a/drivers/net/chelsio/sge.c +++ b/drivers/net/chelsio/sge.c @@ -54,6 +54,7 @@ #include #include #include +#include #include "cpl5_cmd.h" #include "sge.h" diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index cde59b4..11a92af 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -27,6 +27,7 @@ #include #include #include +#include #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) #define BCM_VLAN 1 #endif diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c index cba1401..3f562ba 100644 --- a/drivers/net/cxgb3/sge.c +++ b/drivers/net/cxgb3/sge.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include "common.h" #include "regs.h" diff --git a/drivers/net/cxgb4/sge.c b/drivers/net/cxgb4/sge.c index 75a4b0f..56adf44 100644 --- a/drivers/net/cxgb4/sge.c +++ b/drivers/net/cxgb4/sge.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include "cxgb4.h" diff --git a/drivers/net/cxgb4vf/sge.c b/drivers/net/cxgb4vf/sge.c index 5182960..5fd75fd 100644 --- a/drivers/net/cxgb4vf/sge.c +++ b/drivers/net/cxgb4vf/sge.c @@ -41,6 +41,7 @@ #include #include #include +#include #include "t4vf_common.h" #include "t4vf_defs.h" diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index c18cb8e..76e8af0 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -29,6 +29,7 @@ #include "e1000.h" #include #include +#include /* Intel Media SOC GbE MDIO physical base address */ static unsigned long ce4100_gbe_mdio_base_phy; diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 0939040..d960056 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -49,6 +49,7 @@ #include #include #include +#include #include "e1000.h" diff --git a/drivers/net/ehea/ehea_qmr.h b/drivers/net/ehea/ehea_qmr.h index 3810473..fddff8e 100644 --- a/drivers/net/ehea/ehea_qmr.h +++ b/drivers/net/ehea/ehea_qmr.h @@ -29,6 +29,7 @@ #ifndef __EHEA_QMR_H__ #define __EHEA_QMR_H__ +#include #include "ehea.h" #include "ehea_hw.h" diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c index 3d99b0f..2f433fb 100644 --- a/drivers/net/enic/enic_main.c +++ b/drivers/net/enic/enic_main.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include "cq_enet_desc.h" diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index d09e8b0..537b695 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -64,6 +64,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index ce7838e..0ae9352 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -47,6 +47,7 @@ #include #ifdef CONFIG_IGB_DCA #include +#include #endif #include "igb.h" diff --git a/drivers/net/igbvf/netdev.c b/drivers/net/igbvf/netdev.c index 1d04ca6..1c77fb3 100644 --- a/drivers/net/igbvf/netdev.c +++ b/drivers/net/igbvf/netdev.c @@ -41,6 +41,7 @@ #include #include #include +#include #include "igbvf.h" diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c index 0f681ac..6a130eb 100644 --- a/drivers/net/ixgb/ixgb_main.c +++ b/drivers/net/ixgb/ixgb_main.c @@ -28,6 +28,7 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +#include #include "ixgb.h" char ixgb_driver_name[] = "ixgb"; diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index fa01b0b..08e8e25 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include "ixgbe.h" diff --git a/drivers/net/ixgbevf/ixgbevf_main.c b/drivers/net/ixgbevf/ixgbevf_main.c index d7ab202..28d3cb2 100644 --- a/drivers/net/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ixgbevf/ixgbevf_main.c @@ -44,6 +44,7 @@ #include #include #include +#include #include "ixgbevf.h" diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index b1358f7..bf84849 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c @@ -65,6 +65,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/pasemi_mac.c b/drivers/net/pasemi_mac.c index 828e97c..9ec112c 100644 --- a/drivers/net/pasemi_mac.c +++ b/drivers/net/pasemi_mac.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/pch_gbe/pch_gbe_main.c b/drivers/net/pch_gbe/pch_gbe_main.c index c2476fd..eac3c5c 100644 --- a/drivers/net/pch_gbe/pch_gbe_main.c +++ b/drivers/net/pch_gbe/pch_gbe_main.c @@ -20,6 +20,7 @@ #include "pch_gbe.h" #include "pch_gbe_api.h" +#include #define DRV_VERSION "1.00" const char pch_driver_version[] = DRV_VERSION; diff --git a/drivers/net/qla3xxx.c b/drivers/net/qla3xxx.c index d495a68..771bb61 100644 --- a/drivers/net/qla3xxx.c +++ b/drivers/net/qla3xxx.c @@ -35,6 +35,7 @@ #include #include #include +#include #include "qla3xxx.h" diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index 6c9d124..930ae45 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include "qlge.h" diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 04f4e60..ef1ce2e 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 89cfee7..a9a5f5e 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -78,6 +78,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/sb1250-mac.c b/drivers/net/sb1250-mac.c index d96d2f7..68d5042 100644 --- a/drivers/net/sb1250-mac.c +++ b/drivers/net/sb1250-mac.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/sfc/rx.c b/drivers/net/sfc/rx.c index b7dc891..62e4364 100644 --- a/drivers/net/sfc/rx.c +++ b/drivers/net/sfc/rx.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include "net_driver.h" diff --git a/drivers/net/skge.c b/drivers/net/skge.c index 52a48cb..f4be5c7 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c @@ -44,6 +44,7 @@ #include #include #include +#include #include #include "skge.h" diff --git a/drivers/net/stmmac/stmmac_main.c b/drivers/net/stmmac/stmmac_main.c index e15c4a0..e25e44a 100644 --- a/drivers/net/stmmac/stmmac_main.c +++ b/drivers/net/stmmac/stmmac_main.c @@ -45,6 +45,7 @@ #include #include #include +#include #include "stmmac.h" #define STMMAC_RESOURCE_NAME "stmmaceth" diff --git a/drivers/net/tc35815.c b/drivers/net/tc35815.c index 7ca51ce..4a55a16 100644 --- a/drivers/net/tc35815.c +++ b/drivers/net/tc35815.c @@ -47,6 +47,7 @@ static const char *version = "tc35815.c:v" DRV_VERSION "\n"; #include #include #include +#include #include #include diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c index fc837cf..8ab870a 100644 --- a/drivers/net/vxge/vxge-main.c +++ b/drivers/net/vxge/vxge-main.c @@ -52,6 +52,7 @@ #include #include #include +#include #include "vxge-main.h" #include "vxge-reg.h" diff --git a/drivers/net/vxge/vxge-traffic.c b/drivers/net/vxge/vxge-traffic.c index 2638b8d..f935170 100644 --- a/drivers/net/vxge/vxge-traffic.c +++ b/drivers/net/vxge/vxge-traffic.c @@ -12,6 +12,7 @@ * Copyright(c) 2002-2010 Exar Corp. ******************************************************************************/ #include +#include #include "vxge-traffic.h" #include "vxge-config.h" -- cgit v0.10.2 From 474b4c4ff007c992ea7dc88ba2605aa124f8bafb Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 22 May 2011 20:42:10 -0400 Subject: netlabel: Remove prefetches from list handlers. Signed-off-by: David S. Miller diff --git a/net/netlabel/netlabel_addrlist.h b/net/netlabel/netlabel_addrlist.h index 1c1c093..2b9644e 100644 --- a/net/netlabel/netlabel_addrlist.h +++ b/net/netlabel/netlabel_addrlist.h @@ -96,12 +96,12 @@ static inline struct netlbl_af4list *__af4list_valid_rcu(struct list_head *s, #define netlbl_af4list_foreach(iter, head) \ for (iter = __af4list_valid((head)->next, head); \ - prefetch(iter->list.next), &iter->list != (head); \ + &iter->list != (head); \ iter = __af4list_valid(iter->list.next, head)) #define netlbl_af4list_foreach_rcu(iter, head) \ for (iter = __af4list_valid_rcu((head)->next, head); \ - prefetch(iter->list.next), &iter->list != (head); \ + &iter->list != (head); \ iter = __af4list_valid_rcu(iter->list.next, head)) #define netlbl_af4list_foreach_safe(iter, tmp, head) \ @@ -163,12 +163,12 @@ static inline struct netlbl_af6list *__af6list_valid_rcu(struct list_head *s, #define netlbl_af6list_foreach(iter, head) \ for (iter = __af6list_valid((head)->next, head); \ - prefetch(iter->list.next), &iter->list != (head); \ + &iter->list != (head); \ iter = __af6list_valid(iter->list.next, head)) #define netlbl_af6list_foreach_rcu(iter, head) \ for (iter = __af6list_valid_rcu((head)->next, head); \ - prefetch(iter->list.next), &iter->list != (head); \ + &iter->list != (head); \ iter = __af6list_valid_rcu(iter->list.next, head)) #define netlbl_af6list_foreach_safe(iter, tmp, head) \ -- cgit v0.10.2 From 120a3d5c7c1f37752e7956d296a4f031f38cb217 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 22 May 2011 20:53:43 -0400 Subject: ipv4: Include linux/prefetch.h in fib_trie.c Signed-off-by: David S. Miller diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index c779ce9..dd5a320 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c @@ -67,6 +67,7 @@ #include #include #include +#include #include #include #include -- cgit v0.10.2 From 67f11f4deda0818640decb19a28c537dbe5d429e Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 22 May 2011 20:54:11 -0400 Subject: net: Remove linux/prefetch.h include from linux/skbuff.h No longer needed. Signed-off-by: David S. Miller diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 09901fd..8cac356 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -28,7 +28,6 @@ #include #include #include -#include #include /* Don't change this without changing skb_csum_unnecessary! */ -- cgit v0.10.2 From a37dd3332319260cce81ac91ce25fcc3a31de997 Mon Sep 17 00:00:00 2001 From: David Ward Date: Thu, 19 May 2011 02:53:20 +0000 Subject: macvlan: Forward unicast frames in bridge mode to lowerdev Unicast frames between macvlan interfaces in bridge mode are not otherwise sent to network taps on the lowerdev (as all other macvlan frames are), so forward the frames to the receive queue of the lowerdev first. Signed-off-by: David Ward Signed-off-by: David S. Miller diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index d72a706..d6aeaa5 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c @@ -238,10 +238,8 @@ static int macvlan_queue_xmit(struct sk_buff *skb, struct net_device *dev) dest = macvlan_hash_lookup(port, eth->h_dest); if (dest && dest->mode == MACVLAN_MODE_BRIDGE) { - unsigned int length = skb->len + ETH_HLEN; - int ret = dest->forward(dest->dev, skb); - macvlan_count_rx(dest, length, - ret == NET_RX_SUCCESS, 0); + /* send to lowerdev first for its network taps */ + vlan->forward(vlan->lowerdev, skb); return NET_XMIT_SUCCESS; } -- cgit v0.10.2 From 8d8fc29d02a33e4bd5f4fa47823c1fd386346093 Mon Sep 17 00:00:00 2001 From: Amerigo Wang Date: Thu, 19 May 2011 21:39:10 +0000 Subject: netpoll: disable netpoll when enslave a device V3: rename NETDEV_ENSLAVE to NETDEV_JOIN Currently we do nothing when we enslave a net device which is running netconsole. Neil pointed out that we may get weird results in such case, so let's disable netpoll on the device being enslaved. I think it is too harsh to prevent the device being ensalved if it is running netconsole. By the way, this patch also removes the NETDEV_GOING_DOWN from netconsole netdev notifier, because netpoll will check if the device is running or not and we don't handle NETDEV_PRE_UP neither. This patch is based on net-next-2.6. Signed-off-by: WANG Cong Cc: Neil Horman Signed-off-by: David S. Miller diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 088fd84..f4960f5 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1640,6 +1640,8 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) } } + call_netdevice_notifiers(NETDEV_JOIN, slave_dev); + /* If this is the first slave, then we need to set the master's hardware * address to be the same as the slave's. */ if (is_zero_ether_addr(bond->dev->dev_addr)) diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index a83e101..4190786 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c @@ -621,11 +621,10 @@ static int netconsole_netdev_event(struct notifier_block *this, bool stopped = false; if (!(event == NETDEV_CHANGENAME || event == NETDEV_UNREGISTER || - event == NETDEV_BONDING_DESLAVE || event == NETDEV_GOING_DOWN)) + event == NETDEV_BONDING_DESLAVE || event == NETDEV_JOIN)) goto done; spin_lock_irqsave(&target_list_lock, flags); -restart: list_for_each_entry(nt, &target_list, list) { netconsole_target_get(nt); if (nt->np.dev == dev) { @@ -633,6 +632,8 @@ restart: case NETDEV_CHANGENAME: strlcpy(nt->np.dev_name, dev->name, IFNAMSIZ); break; + case NETDEV_BONDING_DESLAVE: + case NETDEV_JOIN: case NETDEV_UNREGISTER: /* * rtnl_lock already held @@ -647,11 +648,7 @@ restart: dev_put(nt->np.dev); nt->np.dev = NULL; netconsole_target_put(nt); - goto restart; } - /* Fall through */ - case NETDEV_GOING_DOWN: - case NETDEV_BONDING_DESLAVE: nt->enabled = 0; stopped = true; break; @@ -660,10 +657,21 @@ restart: netconsole_target_put(nt); } spin_unlock_irqrestore(&target_list_lock, flags); - if (stopped && (event == NETDEV_UNREGISTER || event == NETDEV_BONDING_DESLAVE)) + if (stopped) { printk(KERN_INFO "netconsole: network logging stopped on " - "interface %s as it %s\n", dev->name, - event == NETDEV_UNREGISTER ? "unregistered" : "released slaves"); + "interface %s as it ", dev->name); + switch (event) { + case NETDEV_UNREGISTER: + printk(KERN_CONT "unregistered\n"); + break; + case NETDEV_BONDING_DESLAVE: + printk(KERN_CONT "released slaves\n"); + break; + case NETDEV_JOIN: + printk(KERN_CONT "is joining a master device\n"); + break; + } + } done: return NOTIFY_DONE; diff --git a/include/linux/notifier.h b/include/linux/notifier.h index 621dfa1..a577762 100644 --- a/include/linux/notifier.h +++ b/include/linux/notifier.h @@ -211,6 +211,7 @@ static inline int notifier_to_errno(int ret) #define NETDEV_UNREGISTER_BATCH 0x0011 #define NETDEV_BONDING_DESLAVE 0x0012 #define NETDEV_NOTIFY_PEERS 0x0013 +#define NETDEV_JOIN 0x0014 #define SYS_DOWN 0x0001 /* Notify of system down */ #define SYS_RESTART SYS_DOWN -- cgit v0.10.2 From bb8ed6302b0613339c1a5f0a2cb0b3807c0af611 Mon Sep 17 00:00:00 2001 From: Amerigo Wang Date: Thu, 19 May 2011 21:39:11 +0000 Subject: bridge: call NETDEV_JOIN notifiers when add a slave In the previous patch I added NETDEV_JOIN, now we can notify netconsole when adding a device to a bridge too. Signed-off-by: WANG Cong Cc: Neil Horman Signed-off-by: David S. Miller diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index 5dbdfdf..d5147dd 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c @@ -338,6 +338,8 @@ int br_add_if(struct net_bridge *br, struct net_device *dev) if (IS_ERR(p)) return PTR_ERR(p); + call_netdevice_notifiers(NETDEV_JOIN, dev); + err = dev_set_promiscuity(dev, 1); if (err) goto put_back; -- cgit v0.10.2 From daf9209bb2c8b07ca025eac82e3d175534086c77 Mon Sep 17 00:00:00 2001 From: Amerigo Wang Date: Thu, 19 May 2011 21:39:12 +0000 Subject: net: rename NETDEV_BONDING_DESLAVE to NETDEV_RELEASE s/NETDEV_BONDING_DESLAVE/NETDEV_RELEASE/ as Andy suggested. Signed-off-by: WANG Cong Cc: Andy Gospodarek Cc: Neil Horman Signed-off-by: David S. Miller diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index f4960f5..6dc4284 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1974,7 +1974,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) } block_netpoll_tx(); - netdev_bonding_change(bond_dev, NETDEV_BONDING_DESLAVE); + netdev_bonding_change(bond_dev, NETDEV_RELEASE); write_lock_bh(&bond->lock); slave = bond_get_slave_by_dev(bond, slave_dev); diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index 4190786..dfc8272 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c @@ -621,7 +621,7 @@ static int netconsole_netdev_event(struct notifier_block *this, bool stopped = false; if (!(event == NETDEV_CHANGENAME || event == NETDEV_UNREGISTER || - event == NETDEV_BONDING_DESLAVE || event == NETDEV_JOIN)) + event == NETDEV_RELEASE || event == NETDEV_JOIN)) goto done; spin_lock_irqsave(&target_list_lock, flags); @@ -632,7 +632,7 @@ static int netconsole_netdev_event(struct notifier_block *this, case NETDEV_CHANGENAME: strlcpy(nt->np.dev_name, dev->name, IFNAMSIZ); break; - case NETDEV_BONDING_DESLAVE: + case NETDEV_RELEASE: case NETDEV_JOIN: case NETDEV_UNREGISTER: /* @@ -664,7 +664,7 @@ static int netconsole_netdev_event(struct notifier_block *this, case NETDEV_UNREGISTER: printk(KERN_CONT "unregistered\n"); break; - case NETDEV_BONDING_DESLAVE: + case NETDEV_RELEASE: printk(KERN_CONT "released slaves\n"); break; case NETDEV_JOIN: diff --git a/include/linux/notifier.h b/include/linux/notifier.h index a577762..c0688b0 100644 --- a/include/linux/notifier.h +++ b/include/linux/notifier.h @@ -209,7 +209,7 @@ static inline int notifier_to_errno(int ret) #define NETDEV_POST_TYPE_CHANGE 0x000F #define NETDEV_POST_INIT 0x0010 #define NETDEV_UNREGISTER_BATCH 0x0011 -#define NETDEV_BONDING_DESLAVE 0x0012 +#define NETDEV_RELEASE 0x0012 #define NETDEV_NOTIFY_PEERS 0x0013 #define NETDEV_JOIN 0x0014 -- cgit v0.10.2 From ac3d3f81516fcbf80416e84682fd4bdaf3080611 Mon Sep 17 00:00:00 2001 From: Amerigo Wang Date: Thu, 19 May 2011 23:06:32 +0000 Subject: rtnetlink: ignore NETDEV_RELEASE and NETDEV_JOIN event These two events are not expected to be caught by userspace. Signed-off-by: WANG Cong Signed-off-by: David S. Miller diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index d2ba259..d1644e3 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -1956,6 +1956,8 @@ static int rtnetlink_event(struct notifier_block *this, unsigned long event, voi case NETDEV_GOING_DOWN: case NETDEV_UNREGISTER: case NETDEV_UNREGISTER_BATCH: + case NETDEV_RELEASE: + case NETDEV_JOIN: break; default: rtmsg_ifinfo(RTM_NEWLINK, dev, 0); -- cgit v0.10.2 From 6df427fe8c481d3be437cbe8bd366bdac82b73c4 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 19 May 2011 19:37:40 +0000 Subject: net: remove synchronize_net() from netdev_set_master() In the old days, we used to access dev->master in __netif_receive_skb() in a rcu_read_lock section. So one synchronize_net() call was needed in netdev_set_master() to make sure another cpu could not use old master while/after we release it. We now use netdev_rx_handler infrastructure and added one synchronize_net() call in bond_release()/bond_release_all() Remove the obsolete synchronize_net() from netdev_set_master() and add one in bridge del_nbp() after its netdev_rx_handler_unregister() call. This makes enslave -d a bit faster. Signed-off-by: Eric Dumazet CC: Jiri Pirko CC: Stephen Hemminger Signed-off-by: David S. Miller diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index d5147dd..1bacca4 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c @@ -147,6 +147,7 @@ static void del_nbp(struct net_bridge_port *p) dev->priv_flags &= ~IFF_BRIDGE_PORT; netdev_rx_handler_unregister(dev); + synchronize_net(); netdev_set_master(dev, NULL); diff --git a/net/core/dev.c b/net/core/dev.c index d945379..bcb05cb 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -4294,10 +4294,8 @@ int netdev_set_master(struct net_device *slave, struct net_device *master) slave->master = master; - if (old) { - synchronize_net(); + if (old) dev_put(old); - } return 0; } EXPORT_SYMBOL(netdev_set_master); -- cgit v0.10.2 From 3137663dfb43bb3e3174e9da81db0c05f395fc1b Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 19 May 2011 23:42:09 +0000 Subject: net: avoid synchronize_rcu() in dev_deactivate_many dev_deactivate_many() issues one synchronize_rcu() call after qdiscs set to noop_qdisc. This call is here to make sure they are no outstanding qdisc-less dev_queue_xmit calls before returning to caller. But in dismantle phase, we dont have to wait, because we wont activate again the device, and we are going to wait one rcu grace period later in rollback_registered_many(). After this patch, device dismantle uses one synchronize_net() and one rcu_barrier() call only, so we have a ~30% speedup and a smaller RTNL latency. Signed-off-by: Eric Dumazet CC: Patrick McHardy , CC: Ben Greear Signed-off-by: David S. Miller diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index c84b659..b1721d7 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c @@ -815,9 +815,17 @@ static bool some_qdisc_is_busy(struct net_device *dev) return false; } +/** + * dev_deactivate_many - deactivate transmissions on several devices + * @head: list of devices to deactivate + * + * This function returns only when all outstanding transmissions + * have completed, unless all devices are in dismantle phase. + */ void dev_deactivate_many(struct list_head *head) { struct net_device *dev; + bool sync_needed = false; list_for_each_entry(dev, head, unreg_list) { netdev_for_each_tx_queue(dev, dev_deactivate_queue, @@ -827,10 +835,15 @@ void dev_deactivate_many(struct list_head *head) &noop_qdisc); dev_watchdog_down(dev); + sync_needed |= !dev->dismantle; } - /* Wait for outstanding qdisc-less dev_queue_xmit calls. */ - synchronize_rcu(); + /* Wait for outstanding qdisc-less dev_queue_xmit calls. + * This is avoided if all devices are in dismantle phase : + * Caller will call synchronize_net() for us + */ + if (sync_needed) + synchronize_net(); /* Wait for outstanding qdisc_run calls. */ list_for_each_entry(dev, head, unreg_list) -- cgit v0.10.2 From c378a9c019cf5e017d1ed24954b54fae7bebd2bc Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Sat, 21 May 2011 07:16:42 +0000 Subject: ipv4: Give backtrace in ip_rt_bug(). Add a stack backtrace to the ip_rt_bug path for debugging Signed-off-by: Dave Jones Signed-off-by: David S. Miller diff --git a/net/ipv4/route.c b/net/ipv4/route.c index b24d58e..52b0b95 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -1665,6 +1665,7 @@ static int ip_rt_bug(struct sk_buff *skb) &ip_hdr(skb)->saddr, &ip_hdr(skb)->daddr, skb->dev ? skb->dev->name : "?"); kfree_skb(skb); + WARN_ON(1); return 0; } -- cgit v0.10.2 From c4264f27e83968ddfe3f0cfe7a33adfb320e1e42 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Sat, 21 May 2011 19:46:09 +0000 Subject: net: skb_trim explicitely check the linearity instead of data_len The purpose of the check on data_len is to check linearity, so use the inline helper for this. No overhead and more explicit. Signed-off-by: Emmanuel Grumbach Signed-off-by: David S. Miller diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 8cac356..aeaad97 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -1442,7 +1442,7 @@ extern int ___pskb_trim(struct sk_buff *skb, unsigned int len); static inline void __skb_trim(struct sk_buff *skb, unsigned int len) { - if (unlikely(skb->data_len)) { + if (unlikely(skb_is_nonlinear(skb))) { WARN_ON(1); return; } -- cgit v0.10.2 From 68d5ac2ed6180567407e4187e206df3ba6466373 Mon Sep 17 00:00:00 2001 From: WANG Cong Date: Sun, 22 May 2011 00:17:11 +0000 Subject: pktgen: use vzalloc_node() instead of vmalloc_node() + memset() Signed-off-by: WANG Cong Cc: "David S. Miller" Signed-off-by: David S. Miller diff --git a/net/core/pktgen.c b/net/core/pktgen.c index 67870e9..3b85c0d 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c @@ -3544,13 +3544,12 @@ static int pktgen_add_device(struct pktgen_thread *t, const char *ifname) return -ENOMEM; strcpy(pkt_dev->odevname, ifname); - pkt_dev->flows = vmalloc_node(MAX_CFLOWS * sizeof(struct flow_state), + pkt_dev->flows = vzalloc_node(MAX_CFLOWS * sizeof(struct flow_state), node); if (pkt_dev->flows == NULL) { kfree(pkt_dev); return -ENOMEM; } - memset(pkt_dev->flows, 0, MAX_CFLOWS * sizeof(struct flow_state)); pkt_dev->removal_mark = 0; pkt_dev->min_pkt_size = ETH_ZLEN; -- cgit v0.10.2 From ce14f8946a294ffa741ec29558a1c7e455cecd3b Mon Sep 17 00:00:00 2001 From: WANG Cong Date: Sun, 22 May 2011 00:52:08 +0000 Subject: pktgen: refactor pg_init() code This also shrinks the object size a little. text data bss dec hex filename 28834 186 8 29028 7164 net/core/pktgen.o 28816 186 8 29010 7152 net/core/pktgen.o.AFTER Signed-off-by: WANG Cong Cc: "David Miller" , Signed-off-by: David S. Miller diff --git a/net/core/pktgen.c b/net/core/pktgen.c index 3b85c0d..f76079c 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c @@ -3707,6 +3707,7 @@ static int __init pg_init(void) { int cpu; struct proc_dir_entry *pe; + int ret = 0; pr_info("%s", version); @@ -3717,11 +3718,10 @@ static int __init pg_init(void) pe = proc_create(PGCTRL, 0600, pg_proc_dir, &pktgen_fops); if (pe == NULL) { pr_err("ERROR: cannot create %s procfs entry\n", PGCTRL); - proc_net_remove(&init_net, PG_PROC_DIR); - return -EINVAL; + ret = -EINVAL; + goto remove_dir; } - /* Register us to receive netdevice events */ register_netdevice_notifier(&pktgen_notifier_block); for_each_online_cpu(cpu) { @@ -3735,13 +3735,18 @@ static int __init pg_init(void) if (list_empty(&pktgen_threads)) { pr_err("ERROR: Initialization failed for all threads\n"); - unregister_netdevice_notifier(&pktgen_notifier_block); - remove_proc_entry(PGCTRL, pg_proc_dir); - proc_net_remove(&init_net, PG_PROC_DIR); - return -ENODEV; + ret = -ENODEV; + goto unregister; } return 0; + + unregister: + unregister_netdevice_notifier(&pktgen_notifier_block); + remove_proc_entry(PGCTRL, pg_proc_dir); + remove_dir: + proc_net_remove(&init_net, PG_PROC_DIR); + return ret; } static void __exit pg_cleanup(void) -- cgit v0.10.2 From 792d4b5cb16b684958c2590f77688667ddec1f61 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Sun, 22 May 2011 07:08:11 +0000 Subject: net: filter: move forward declarations to avoid compile warnings Get rid of this compile warning: In file included from arch/s390/kernel/compat_linux.c:37:0: include/linux/filter.h:139:23: warning: 'struct sk_buff' declared inside parameter list Signed-off-by: Heiko Carstens Signed-off-by: David S. Miller diff --git a/include/linux/filter.h b/include/linux/filter.h index 4609b85..9ee3f9f 100644 --- a/include/linux/filter.h +++ b/include/linux/filter.h @@ -131,6 +131,10 @@ struct sock_fprog { /* Required for SO_ATTACH_FILTER. */ #define SKF_LL_OFF (-0x200000) #ifdef __KERNEL__ + +struct sk_buff; +struct sock; + struct sk_filter { atomic_t refcnt; @@ -146,9 +150,6 @@ static inline unsigned int sk_filter_len(const struct sk_filter *fp) return fp->len * sizeof(struct sock_filter) + sizeof(*fp); } -struct sk_buff; -struct sock; - extern int sk_filter(struct sock *sk, struct sk_buff *skb); extern unsigned int sk_run_filter(const struct sk_buff *skb, const struct sock_filter *filter); -- cgit v0.10.2 From 40955532bc9d865999dfc58b7896605d58650655 Mon Sep 17 00:00:00 2001 From: Vladislav Zolotarov Date: Sun, 22 May 2011 10:06:58 +0000 Subject: bnx2x: call dev_kfree_skb_any instead of dev_kfree_skb replace function calls when possible call in both irq/non-irq contexts Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index 64d01e7..d5bd35b 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -131,7 +131,7 @@ static u16 bnx2x_free_tx_pkt(struct bnx2x *bp, struct bnx2x_fastpath *fp, /* release skb */ WARN_ON(!skb); - dev_kfree_skb(skb); + dev_kfree_skb_any(skb); tx_buf->first_bd = 0; tx_buf->skb = NULL; @@ -465,7 +465,7 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp, } else { DP(NETIF_MSG_RX_STATUS, "Failed to allocate new pages" " - dropping packet!\n"); - dev_kfree_skb(skb); + dev_kfree_skb_any(skb); } diff --git a/drivers/net/bnx2x/bnx2x_cmn.h b/drivers/net/bnx2x/bnx2x_cmn.h index fab161e..1a3545b 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.h +++ b/drivers/net/bnx2x/bnx2x_cmn.h @@ -840,7 +840,7 @@ static inline int bnx2x_alloc_rx_skb(struct bnx2x *bp, mapping = dma_map_single(&bp->pdev->dev, skb->data, fp->rx_buf_size, DMA_FROM_DEVICE); if (unlikely(dma_mapping_error(&bp->pdev->dev, mapping))) { - dev_kfree_skb(skb); + dev_kfree_skb_any(skb); return -ENOMEM; } -- cgit v0.10.2 From c3a8ce6145cfcfce192513187000cd723313d94f Mon Sep 17 00:00:00 2001 From: Vladislav Zolotarov Date: Sun, 22 May 2011 10:08:09 +0000 Subject: bnx2x: properly handle CFC DEL in cnic flow Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index f45c0ca..fb23d57 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -3666,7 +3666,8 @@ static int bnx2x_cnic_handle_cfc_del(struct bnx2x *bp, u32 cid, union event_ring_elem *elem) { if (!bp->cnic_eth_dev.starting_cid || - cid < bp->cnic_eth_dev.starting_cid) + (cid < bp->cnic_eth_dev.starting_cid && + cid != bp->cnic_eth_dev.iscsi_l2_cid)) return 1; DP(BNX2X_MSG_SP, "got delete ramrod for CNIC CID %d\n", cid); -- cgit v0.10.2 From 5e374b5aeb9a030c1859b3054e3b36dea3b29cfc Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Sun, 22 May 2011 10:09:19 +0000 Subject: bnx2x: fix DMAE timeout according to hw specifications Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index fb23d57..f7abebf 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -571,7 +571,7 @@ static int bnx2x_issue_dmae_with_comp(struct bnx2x *bp, struct dmae_command *dmae) { u32 *wb_comp = bnx2x_sp(bp, wb_comp); - int cnt = CHIP_REV_IS_SLOW(bp) ? (400000) : 40; + int cnt = CHIP_REV_IS_SLOW(bp) ? (400000) : 4000; int rc = 0; DP(BNX2X_MSG_OFF, "data before [0x%08x 0x%08x 0x%08x 0x%08x]\n", -- cgit v0.10.2 From 1b6e2ceb4745b5838cb94463131d19dbea6cf0e3 Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Sun, 22 May 2011 10:11:26 +0000 Subject: bnx2x: allow device properly initialize after hotplug Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index f7abebf..a97d9be 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -7288,51 +7288,35 @@ static inline void bnx2x_mcp_wait_one(struct bnx2x *bp) msleep(MCP_ONE_TIMEOUT); } -static int bnx2x_reset_mcp_comp(struct bnx2x *bp, u32 magic_val) +/* + * initializes bp->common.shmem_base and waits for validity signature to appear + */ +static int bnx2x_init_shmem(struct bnx2x *bp) { - u32 shmem, cnt, validity_offset, val; - int rc = 0; - - msleep(100); + int cnt = 0; + u32 val = 0; - /* Get shmem offset */ - shmem = REG_RD(bp, MISC_REG_SHARED_MEM_ADDR); - if (shmem == 0) { - BNX2X_ERR("Shmem 0 return failure\n"); - rc = -ENOTTY; - goto exit_lbl; - } + do { + bp->common.shmem_base = REG_RD(bp, MISC_REG_SHARED_MEM_ADDR); + if (bp->common.shmem_base) { + val = SHMEM_RD(bp, validity_map[BP_PORT(bp)]); + if (val & SHR_MEM_VALIDITY_MB) + return 0; + } - validity_offset = offsetof(struct shmem_region, validity_map[0]); + bnx2x_mcp_wait_one(bp); - /* Wait for MCP to come up */ - for (cnt = 0; cnt < (MCP_TIMEOUT / MCP_ONE_TIMEOUT); cnt++) { - /* TBD: its best to check validity map of last port. - * currently checks on port 0. - */ - val = REG_RD(bp, shmem + validity_offset); - DP(NETIF_MSG_HW, "shmem 0x%x validity map(0x%x)=0x%x\n", shmem, - shmem + validity_offset, val); + } while (cnt++ < (MCP_TIMEOUT / MCP_ONE_TIMEOUT)); - /* check that shared memory is valid. */ - if ((val & (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB)) - == (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB)) - break; + BNX2X_ERR("BAD MCP validity signature\n"); - bnx2x_mcp_wait_one(bp); - } - - DP(NETIF_MSG_HW, "Cnt=%d Shmem validity map 0x%x\n", cnt, val); + return -ENODEV; +} - /* Check that shared memory is valid. This indicates that MCP is up. */ - if ((val & (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB)) != - (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB)) { - BNX2X_ERR("Shmem signature not present. MCP is not up !!\n"); - rc = -ENOTTY; - goto exit_lbl; - } +static int bnx2x_reset_mcp_comp(struct bnx2x *bp, u32 magic_val) +{ + int rc = bnx2x_init_shmem(bp); -exit_lbl: /* Restore the `magic' bit value */ if (!CHIP_IS_E1(bp)) bnx2x_clp_reset_done(bp, magic_val); @@ -7845,10 +7829,12 @@ static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp) BNX2X_DEV_INFO("flash_size 0x%x (%d)\n", bp->common.flash_size, bp->common.flash_size); - bp->common.shmem_base = REG_RD(bp, MISC_REG_SHARED_MEM_ADDR); + bnx2x_init_shmem(bp); + bp->common.shmem2_base = REG_RD(bp, (BP_PATH(bp) ? MISC_REG_GENERIC_CR_1 : MISC_REG_GENERIC_CR_0)); + bp->link_params.shmem_base = bp->common.shmem_base; bp->link_params.shmem2_base = bp->common.shmem2_base; BNX2X_DEV_INFO("shmem offset 0x%x shmem2 offset 0x%x\n", @@ -7860,11 +7846,6 @@ static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp) return; } - val = SHMEM_RD(bp, validity_map[BP_PORT(bp)]); - if ((val & (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB)) - != (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB)) - BNX2X_ERR("BAD MCP validity signature\n"); - bp->common.hw_config = SHMEM_RD(bp, dev_info.shared_hw_config.config); BNX2X_DEV_INFO("hw_config 0x%08x\n", bp->common.hw_config); -- cgit v0.10.2