浏览代码

pcmcia: avoid sysfs-related lockup for cardbus

In cb_free(), we remove some sysfs files -- other sysfs files might
grab ops_mutex, so we cannot hold it while removing sysfs files. This
fixes http://lkml.org/lkml/2010/1/17/88 .

Tested-by: Wolfram Sang <w.sang@pengutronix.de>
Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
Dominik Brodowski 15 年之前
父节点
当前提交
c3bfc96ef7
共有 1 个文件被更改,包括 10 次插入2 次删除
  1. 10 2
      drivers/pcmcia/cs.c

+ 10 - 2
drivers/pcmcia/cs.c

@@ -400,10 +400,19 @@ static void socket_shutdown(struct pcmcia_socket *s)
 	s->lock_count = 0;
 	s->lock_count = 0;
 	kfree(s->fake_cis);
 	kfree(s->fake_cis);
 	s->fake_cis = NULL;
 	s->fake_cis = NULL;
+	s->functions = 0;
+
+	/* From here on we can be sure that only we (that is, the
+	 * pccardd thread) accesses this socket, and all (16-bit)
+	 * PCMCIA interactions are gone. Therefore, release
+	 * ops_mutex so that we don't get a sysfs-related lockdep
+	 * warning.
+	 */
+	mutex_unlock(&s->ops_mutex);
+
 #ifdef CONFIG_CARDBUS
 #ifdef CONFIG_CARDBUS
 	cb_free(s);
 	cb_free(s);
 #endif
 #endif
-	s->functions = 0;
 
 
 	/* give socket some time to power down */
 	/* give socket some time to power down */
 	msleep(100);
 	msleep(100);
@@ -415,7 +424,6 @@ static void socket_shutdown(struct pcmcia_socket *s)
 	}
 	}
 
 
 	s->state &= ~SOCKET_INUSE;
 	s->state &= ~SOCKET_INUSE;
-	mutex_unlock(&s->ops_mutex);
 }
 }
 
 
 static int socket_setup(struct pcmcia_socket *skt, int initial_delay)
 static int socket_setup(struct pcmcia_socket *skt, int initial_delay)