From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1761622AbZEMVb3 (ORCPT ); Wed, 13 May 2009 17:31:29 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1761330AbZEMVbR (ORCPT ); Wed, 13 May 2009 17:31:17 -0400 Received: from vena.lwn.net ([206.168.112.25]:33019 "EHLO vena.lwn.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1761188AbZEMVbQ (ORCPT ); Wed, 13 May 2009 17:31:16 -0400 Date: Wed, 13 May 2009 15:31:12 -0600 From: Jonathan Corbet To: Wolfgang Grandegger Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Wolfgang Grandegger , Oliver Hartkopp Subject: Re: [PATCH v2 3/7] [PATCH 3/8] can: CAN Network device driver and Netlink interface Message-ID: <20090513153112.0822809b@bike.lwn.net> In-Reply-To: <20090512092757.574693100@denx.de> References: <20090512092757.048938233@denx.de> <20090512092757.574693100@denx.de> Organization: LWN.net X-Mailer: Claws Mail 3.7.1 (GTK+ 2.16.1; x86_64-redhat-linux-gnu) Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org [Quick review ...] > +/* > + * CAN device restart for bus-off recovery > + */ > +int can_restart_now(struct net_device *dev) > +{ > + struct can_priv *priv = netdev_priv(dev); > + struct net_device_stats *stats = &dev->stats; > + struct sk_buff *skb; > + struct can_frame *cf; > + int err; > + > + /* Synchronize with dev->hard_start_xmit() */ > + netif_tx_lock(dev); > + > + /* Ensure that no more messages can go out */ > + if (netif_carrier_ok(dev)) > + netif_carrier_off(dev); > + > + /* Ensure that no more messages can come in */ > + err = priv->do_set_mode(dev, CAN_MODE_STOP); > + if (err) > + return err; This leaves _xmit_lock held and carrier off. Is that really what you want to do? > + > + /* Now it's save to clean up */ > + del_timer_sync(&priv->restart_timer); > + can_flush_echo_skb(dev); > + > + dev_dbg(dev->dev.parent, "restarted\n"); > + priv->can_stats.restarts++; > + > + /* send restart message upstream */ > + skb = dev_alloc_skb(sizeof(struct can_frame)); > + if (skb == NULL) > + return -ENOMEM; ...here too... > + skb->dev = dev; > + skb->protocol = htons(ETH_P_CAN); > + cf = (struct can_frame *)skb_put(skb, sizeof(struct can_frame)); > + memset(cf, 0, sizeof(struct can_frame)); > + cf->can_id = CAN_ERR_FLAG | CAN_ERR_RESTARTED; > + cf->can_dlc = CAN_ERR_DLC; > + > + netif_rx(skb); > + > + dev->last_rx = jiffies; > + stats->rx_packets++; > + stats->rx_bytes += cf->can_dlc; > + > + /* Now restart the device */ > + err = priv->do_set_mode(dev, CAN_MODE_START); > + if (err) > + return err; ...and here too. Do you maybe want to get rid of the middle-of-function returns and switch to the "goto out" convention? > + netif_carrier_on(dev); > + > + netif_tx_unlock(dev); > + > + return 0; > +} > + > +static void can_restart_after(unsigned long data) > +{ > + struct net_device *dev = (struct net_device *)data; > + > + can_restart_now(dev); > +} can_restart_after what? I find myself confused by this function and wondering why it exists. jon