fix module reference counting in zoran driver
Subsystems (3)
PATCH 1/1 fix module reference counting in zoran driver
Take a reference before calling into the module and release it after we're done. Also remove the useless (and wrong) refcounting in videocodec - symbols from this module are used by other modules if we call into those functions so it can't be unloaded anyway.
We really need to add a debug check to tip all those try_module_get(THIS_MODULE) callers..
drivers/media/video/videocodec.c +13 -42
@@ -108,13 +108,17 @@if ((master->flags & h->codec->flags) == master->flags) {dprintk (4 ,"videocodec_attach: try '%s'\n" , h->codec->name); + +if (!try_module_get (h->codec->owner)) +return NULL ; + codec =kmalloc (sizeof (struct videocodec ),GFP_KERNEL );if (!codec) {dprintk (1 ,KERN_ERR "videocodec_attach: no mem\n" ); -return NULL ; + goto out_module_put; }memcpy (codec, h->codec,sizeof (struct videocodec ));
@@ -132,26 +136,12 @@dprintk (1 ,KERN_ERR "videocodec_attach: no memory\n" ); -kfree (codec); -return NULL ; + goto out_kfree; }memset (ptr,0 ,sizeof (struct attached_list )); ptr->codec = codec; -#if LINUX_VERSION_CODE <KERNEL_VERSION (2 ,5 ,0 ) -MOD_INC_USE_COUNT ; -#else -if (!try_module_get (THIS_MODULE )) { -dprintk (1 , -KERN_ERR -"videocodec: failed to increment usecount\n" ); -kfree (codec); -kfree (ptr); -return NULL ; - } -#endif - a = h->list;if (!a) { h->list = ptr;
@@ -177,6 +167,12 @@dprintk (1 ,KERN_ERR "videocodec_attach: no codec found!\n" );return NULL ; + + out_module_put: +module_put (h->codec->owner); + out_kfree: +kfree (codec); +return NULL ; }int
@@ -228,16 +224,10 @@dprintk (4 ,"videocodec: delete middle\n" ); } +module_put (a->codec->owner);kfree (a->codec);kfree (a); h->attached -=1 ; - -#if LINUX_VERSION_CODE <KERNEL_VERSION (2 ,5 ,0 ) -MOD_DEC_USE_COUNT ; -#else -module_put (THIS_MODULE ); -#endif -return 0 ; } prev = a;
@@ -274,18 +264,6 @@memset (ptr,0 ,sizeof (struct codec_list )); ptr->codec = codec; -#if LINUX_VERSION_CODE <KERNEL_VERSION (2 ,5 ,0 ) -MOD_INC_USE_COUNT ; -#else -if (!try_module_get (THIS_MODULE )) { -dprintk (1 , -KERN_ERR -"videocodec: failed to increment module count\n" ); -kfree (ptr); -return -ENODEV ; - } -#endif -if (!h) { codeclist_top = ptr;dprintk (4 ,"videocodec: hooked in as first element\n" );
@@ -342,13 +320,6 @@ "videocodec: delete middle element\n"); }kfree (h); - -#if LINUX_VERSION_CODE <KERNEL_VERSION (2 ,5 ,0 ) -MOD_DEC_USE_COUNT ; -#else -module_put (THIS_MODULE ); -#endif -return 0 ; } prev = h;
===== drivers/media/video/videocodec.h 1.1 vs edited =====
drivers/media/video/videocodec.h +1 -0
@@ -249,6 +249,7 @@ };struct videocodec { +struct module *owner;/* -- filled in by slave device during register -- */ char name[32 ];unsigned long magic;/* may be used for client<->master attaching */
===== drivers/media/video/zr36016.c 1.1 vs edited =====
drivers/media/video/zr36016.c +1 -19
@@ -422,12 +422,6 @@ codec->data =NULL ; zr36016_codecs--; -#if LINUX_VERSION_CODE <KERNEL_VERSION (2 ,5 ,0 ) -MOD_DEC_USE_COUNT ; -#else -module_put (THIS_MODULE ); -#endif -return 0 ; }
@@ -470,19 +464,6 @@ ptr->num = zr36016_codecs++; ptr->codec = codec; -#if LINUX_VERSION_CODE <KERNEL_VERSION (2 ,5 ,0 ) -MOD_INC_USE_COUNT ; -#else -if (!try_module_get (THIS_MODULE )) { -dprintk (1 , -KERN_ERR -"zr36016: failed to increase module use count\n" ); -kfree (ptr); - zr36016_codecs--; -return -ENODEV ; - } -#endif -//testing res =zr36016_basic_test (ptr);if (res <0 ) {
@@ -504,6 +485,7 @@ }static const struct videocodec zr36016_codec = { + .owner =THIS_MODULE , .name ="zr36016" , .magic =0L ,// magic not used .flags =
===== drivers/media/video/zr36050.c 1.1 vs edited =====
drivers/media/video/zr36050.c +1 -19
@@ -737,12 +737,6 @@ codec->data =NULL ; zr36050_codecs--; -#if LINUX_VERSION_CODE <KERNEL_VERSION (2 ,5 ,0 ) -MOD_DEC_USE_COUNT ; -#else -module_put (THIS_MODULE ); -#endif -return 0 ; }
@@ -785,19 +779,6 @@ ptr->num = zr36050_codecs++; ptr->codec = codec; -#if LINUX_VERSION_CODE <KERNEL_VERSION (2 ,5 ,0 ) -MOD_INC_USE_COUNT ; -#else -if (!try_module_get (THIS_MODULE )) { -dprintk (1 , -KERN_ERR -"zr36050: failed to increase module use count\n" ); -kfree (ptr); - zr36050_codecs--; -return -ENODEV ; - } -#endif -//testing res =zr36050_basic_test (ptr);if (res <0 ) {
@@ -826,6 +807,7 @@ }static const struct videocodec zr36050_codec = { + .owner =THIS_MODULE , .name ="zr36050" , .magic =0L ,// magic not used .flags =
===== drivers/media/video/zr36060.c 1.1 vs edited =====
drivers/media/video/zr36060.c +1 -19
@@ -868,12 +868,6 @@ codec->data =NULL ; zr36060_codecs--; -#if LINUX_VERSION_CODE <KERNEL_VERSION (2 ,5 ,0 ) -MOD_DEC_USE_COUNT ; -#else -module_put (THIS_MODULE ); -#endif -return 0 ; }
@@ -916,19 +910,6 @@ ptr->num = zr36060_codecs++; ptr->codec = codec; -#if LINUX_VERSION_CODE <KERNEL_VERSION (2 ,5 ,0 ) -MOD_INC_USE_COUNT ; -#else -if (!try_module_get (THIS_MODULE )) { -dprintk (1 , -KERN_ERR -"zr36060: failed to increase module use count\n" ); -kfree (ptr); - zr36060_codecs--; -return -ENODEV ; - } -#endif -//testing res =zr36060_basic_test (ptr);if (res <0 ) {
@@ -958,6 +939,7 @@ }static const struct videocodec zr36060_codec = { + .owner =THIS_MODULE , .name ="zr36060" , .magic =0L ,// magic not used .flags =
===== drivers/scsi/megaraid.c 1.59 vs edited =====
drivers/scsi/megaraid.c +1 -0
@@ -4614,6 +4614,7 @@ }static struct scsi_host_template megaraid_template = { + .module =THIS_MODULE , .name ="MegaRAID" , .proc_name ="megaraid" , .info = megaraid_info,