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