Mailing List archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[linux-dvb] [PATCH] fix oops from removing running dvb_net



HI Holger et all

Sometimes I ask myself, why do *I* have to fix this,
but anyway, I did it.

PROBLEM: if there's e.g. active dvb0_0 interface, and
dvb-ttpci (or budget) module is removed, the kernel
will oops quite soon from unclean network interfaces.

FIX: 
apply MOD_INC_USE_COUNT when ifconfig dvb0_0 inet 1.2.3.4
apply MOD_DEC_USE_COUNT when ifconfig dvb0_0 down

this will mark module in use and prvent removal before
all of the network interfaces have been shut down.

side effect: if e.g. vdr is running, a high module usage 
cont will be shown (cca 10-12) but it will drop down
correctly when vdr is stopped.

please apply to CVS

It fixes dvb-s and budget cards. other card types 
need to apply similar technology if they want to avoid 
crashing when playing with net interfaces.

Emard
diff -pur --ignore-space-change dvb-kernel.orig/linux/drivers/media/dvb/dvb-core/dvb_net.c dvb-kernel/linux/drivers/media/dvb/dvb-core/dvb_net.c
--- dvb-kernel.orig/linux/drivers/media/dvb/dvb-core/dvb_net.c	2003-12-12 22:22:19.000000000 +0100
+++ dvb-kernel/linux/drivers/media/dvb/dvb-core/dvb_net.c	2003-12-13 00:03:18.000000000 +0100
@@ -306,7 +306,7 @@ static int dvb_net_feed_start(struct net
 	return 0;
 }
 
-static void dvb_net_feed_stop(struct net_device *dev)
+static int dvb_net_feed_stop(struct net_device *dev)
 {
 	struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv;
 	int i;
@@ -337,7 +337,11 @@ static void dvb_net_feed_stop(struct net
 		priv->demux->release_section_feed(priv->demux, priv->secfeed);
 		priv->secfeed=0;
 	} else
+	{
 		printk("%s: no feed to stop\n", dev->name);
+		return -1;
+	}
+	return 0;
 }
 
 
@@ -360,7 +364,8 @@ static void wq_set_multicast_list (void 
 	struct net_device *dev = data;
 	struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv;
 
-	dvb_net_feed_stop(dev);
+	if(dvb_net_feed_stop(dev))
+		return; // no feed to stop
 
 	priv->rx_mode = RX_MODE_UNI;
 	
@@ -388,7 +393,7 @@ static void wq_set_multicast_list (void 
 	}
 
 		dvb_net_feed_start(dev);
-	}
+}
 
 
 static void dvb_net_set_multicast_list (struct net_device *dev)
@@ -592,6 +597,11 @@ static int dvb_net_remove_if(struct dvb_
 	if (priv->in_use)
 		return -EBUSY;
 
+	if (netif_running(&dvbnet->device[num]))
+	{
+		printk("dvb_net.c: WARNING attempt to remove netif in use\n");
+		return -EBUSY;
+	}
 	dvb_net_stop(&dvbnet->device[num]);
 	flush_scheduled_work();
 	kfree(priv);
Only in dvb-kernel/linux/drivers/media/dvb/dvb-core: dvb_net.c.orig
Only in dvb-kernel/linux/drivers/media/dvb/dvb-core: dvb_net.c~
diff -pur --ignore-space-change dvb-kernel.orig/linux/drivers/media/dvb/ttpci/av7110.c dvb-kernel/linux/drivers/media/dvb/ttpci/av7110.c
--- dvb-kernel.orig/linux/drivers/media/dvb/ttpci/av7110.c	2003-12-12 22:22:18.000000000 +0100
+++ dvb-kernel/linux/drivers/media/dvb/ttpci/av7110.c	2003-12-13 00:04:41.000000000 +0100
@@ -3231,7 +3231,7 @@ static int av7110_start_feed(struct dvb_
         
         if (feed->type == DMX_TYPE_SEC) {
                 int i;
-
+		MOD_INC_USE_COUNT;
 	        for (i=0; i<demux->filternum; i++) {
 		        if (demux->filter[i].state!=DMX_STATE_READY)
 			        continue;
@@ -3275,7 +3275,7 @@ static int av7110_stop_feed(struct dvb_d
         
         if (feed->type == DMX_TYPE_SEC) {
                 int i;
-
+		MOD_DEC_USE_COUNT;
 	        for (i=0; i<demux->filternum; i++)
 		        if (demux->filter[i].state==DMX_STATE_GO && 
 			    demux->filter[i].filter.parent==&feed->feed.sec) {
diff -pur --ignore-space-change dvb-kernel.orig/linux/drivers/media/dvb/ttpci/budget-core.c dvb-kernel/linux/drivers/media/dvb/ttpci/budget-core.c
--- dvb-kernel.orig/linux/drivers/media/dvb/ttpci/budget-core.c	2003-12-12 22:22:18.000000000 +0100
+++ dvb-kernel/linux/drivers/media/dvb/ttpci/budget-core.c	2003-12-12 21:47:17.000000000 +0100
@@ -10,7 +10,7 @@ int budget_debug = 0;
 static int stop_ts_capture(struct budget *budget)
 {
 	DEB_EE(("budget: %p\n",budget));
-
+	MOD_DEC_USE_COUNT;
         if (--budget->feeding)
                 return budget->feeding;
 
@@ -25,7 +25,7 @@ static int start_ts_capture (struct budg
         struct saa7146_dev *dev=budget->dev;
 
 	DEB_EE(("budget: %p\n",budget));
-
+	MOD_INC_USE_COUNT;
         if (budget->feeding) 
                 return ++budget->feeding;
 

Home | Main Index | Thread Index