aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2016-09-23 07:13:55 -0400
committerDavid S. Miller <davem@davemloft.net>2016-09-23 07:13:55 -0400
commitf44ace4d06aab8210d29c731f70b657a7524198b (patch)
tree1ed4182b585c331e465a2f9d200c2065789e6b50
parent3d4357fba82b3cf19ebf0a04d1c9cb086af15d02 (diff)
parent9abefcb1aaa58b9d5aa40a8bb12c87d02415e4c8 (diff)
Merge tag 'linux-can-fixes-for-4.8-20160922' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can
Marc Kleine-Budde says: ==================== pull-request: can 2016-09-22 this is a pull request of one patch for the upcoming linux-4.8 release. The patch by Sergei Miroshnichenko fixes a potential deadlock in the generic CAN device code that cann occour after a bus-off. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/can/dev.c27
-rw-r--r--include/linux/can/dev.h3
2 files changed, 19 insertions, 11 deletions
diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c
index e21f7cc5ae4d..8d6208c0b400 100644
--- a/drivers/net/can/dev.c
+++ b/drivers/net/can/dev.c
@@ -21,6 +21,7 @@
21#include <linux/slab.h> 21#include <linux/slab.h>
22#include <linux/netdevice.h> 22#include <linux/netdevice.h>
23#include <linux/if_arp.h> 23#include <linux/if_arp.h>
24#include <linux/workqueue.h>
24#include <linux/can.h> 25#include <linux/can.h>
25#include <linux/can/dev.h> 26#include <linux/can/dev.h>
26#include <linux/can/skb.h> 27#include <linux/can/skb.h>
@@ -501,9 +502,8 @@ EXPORT_SYMBOL_GPL(can_free_echo_skb);
501/* 502/*
502 * CAN device restart for bus-off recovery 503 * CAN device restart for bus-off recovery
503 */ 504 */
504static void can_restart(unsigned long data) 505static void can_restart(struct net_device *dev)
505{ 506{
506 struct net_device *dev = (struct net_device *)data;
507 struct can_priv *priv = netdev_priv(dev); 507 struct can_priv *priv = netdev_priv(dev);
508 struct net_device_stats *stats = &dev->stats; 508 struct net_device_stats *stats = &dev->stats;
509 struct sk_buff *skb; 509 struct sk_buff *skb;
@@ -543,6 +543,14 @@ restart:
543 netdev_err(dev, "Error %d during restart", err); 543 netdev_err(dev, "Error %d during restart", err);
544} 544}
545 545
546static void can_restart_work(struct work_struct *work)
547{
548 struct delayed_work *dwork = to_delayed_work(work);
549 struct can_priv *priv = container_of(dwork, struct can_priv, restart_work);
550
551 can_restart(priv->dev);
552}
553
546int can_restart_now(struct net_device *dev) 554int can_restart_now(struct net_device *dev)
547{ 555{
548 struct can_priv *priv = netdev_priv(dev); 556 struct can_priv *priv = netdev_priv(dev);
@@ -556,8 +564,8 @@ int can_restart_now(struct net_device *dev)
556 if (priv->state != CAN_STATE_BUS_OFF) 564 if (priv->state != CAN_STATE_BUS_OFF)
557 return -EBUSY; 565 return -EBUSY;
558 566
559 /* Runs as soon as possible in the timer context */ 567 cancel_delayed_work_sync(&priv->restart_work);
560 mod_timer(&priv->restart_timer, jiffies); 568 can_restart(dev);
561 569
562 return 0; 570 return 0;
563} 571}
@@ -578,8 +586,8 @@ void can_bus_off(struct net_device *dev)
578 netif_carrier_off(dev); 586 netif_carrier_off(dev);
579 587
580 if (priv->restart_ms) 588 if (priv->restart_ms)
581 mod_timer(&priv->restart_timer, 589 schedule_delayed_work(&priv->restart_work,
582 jiffies + (priv->restart_ms * HZ) / 1000); 590 msecs_to_jiffies(priv->restart_ms));
583} 591}
584EXPORT_SYMBOL_GPL(can_bus_off); 592EXPORT_SYMBOL_GPL(can_bus_off);
585 593
@@ -688,6 +696,7 @@ struct net_device *alloc_candev(int sizeof_priv, unsigned int echo_skb_max)
688 return NULL; 696 return NULL;
689 697
690 priv = netdev_priv(dev); 698 priv = netdev_priv(dev);
699 priv->dev = dev;
691 700
692 if (echo_skb_max) { 701 if (echo_skb_max) {
693 priv->echo_skb_max = echo_skb_max; 702 priv->echo_skb_max = echo_skb_max;
@@ -697,7 +706,7 @@ struct net_device *alloc_candev(int sizeof_priv, unsigned int echo_skb_max)
697 706
698 priv->state = CAN_STATE_STOPPED; 707 priv->state = CAN_STATE_STOPPED;
699 708
700 init_timer(&priv->restart_timer); 709 INIT_DELAYED_WORK(&priv->restart_work, can_restart_work);
701 710
702 return dev; 711 return dev;
703} 712}
@@ -778,8 +787,6 @@ int open_candev(struct net_device *dev)
778 if (!netif_carrier_ok(dev)) 787 if (!netif_carrier_ok(dev))
779 netif_carrier_on(dev); 788 netif_carrier_on(dev);
780 789
781 setup_timer(&priv->restart_timer, can_restart, (unsigned long)dev);
782
783 return 0; 790 return 0;
784} 791}
785EXPORT_SYMBOL_GPL(open_candev); 792EXPORT_SYMBOL_GPL(open_candev);
@@ -794,7 +801,7 @@ void close_candev(struct net_device *dev)
794{ 801{
795 struct can_priv *priv = netdev_priv(dev); 802 struct can_priv *priv = netdev_priv(dev);
796 803
797 del_timer_sync(&priv->restart_timer); 804 cancel_delayed_work_sync(&priv->restart_work);
798 can_flush_echo_skb(dev); 805 can_flush_echo_skb(dev);
799} 806}
800EXPORT_SYMBOL_GPL(close_candev); 807EXPORT_SYMBOL_GPL(close_candev);
diff --git a/include/linux/can/dev.h b/include/linux/can/dev.h
index 5261751f6bd4..5f5270941ba0 100644
--- a/include/linux/can/dev.h
+++ b/include/linux/can/dev.h
@@ -32,6 +32,7 @@ enum can_mode {
32 * CAN common private data 32 * CAN common private data
33 */ 33 */
34struct can_priv { 34struct can_priv {
35 struct net_device *dev;
35 struct can_device_stats can_stats; 36 struct can_device_stats can_stats;
36 37
37 struct can_bittiming bittiming, data_bittiming; 38 struct can_bittiming bittiming, data_bittiming;
@@ -47,7 +48,7 @@ struct can_priv {
47 u32 ctrlmode_static; /* static enabled options for driver/hardware */ 48 u32 ctrlmode_static; /* static enabled options for driver/hardware */
48 49
49 int restart_ms; 50 int restart_ms;
50 struct timer_list restart_timer; 51 struct delayed_work restart_work;
51 52
52 int (*do_set_bittiming)(struct net_device *dev); 53 int (*do_set_bittiming)(struct net_device *dev);
53 int (*do_set_data_bittiming)(struct net_device *dev); 54 int (*do_set_data_bittiming)(struct net_device *dev);