diff options
author | Sowmini Varadhan <sowmini.varadhan@oracle.com> | 2014-09-16 11:37:08 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-09-16 21:31:31 -0400 |
commit | c21c4ab0d6921f7160a43216fa6973b5924de561 (patch) | |
tree | 8f850b4f2103eace27bf0f4320042d98562043e4 /arch | |
parent | 05aa1651e8b9ca078b1808a2fe7b50703353ec02 (diff) |
sparc64: Move request_irq() from ldc_bind() to ldc_alloc()
The request_irq() needs to be done from ldc_alloc()
to avoid the following (caught by lockdep)
[00000000004a0738] __might_sleep+0xf8/0x120
[000000000058bea4] kmem_cache_alloc_trace+0x184/0x2c0
[00000000004faf80] request_threaded_irq+0x80/0x160
[000000000044f71c] ldc_bind+0x7c/0x220
[0000000000452454] vio_port_up+0x54/0xe0
[00000000101f6778] probe_disk+0x38/0x220 [sunvdc]
[00000000101f6b8c] vdc_port_probe+0x22c/0x300 [sunvdc]
[0000000000451a88] vio_device_probe+0x48/0x60
[000000000074c56c] really_probe+0x6c/0x300
[000000000074c83c] driver_probe_device+0x3c/0xa0
[000000000074c92c] __driver_attach+0x8c/0xa0
[000000000074a6ec] bus_for_each_dev+0x6c/0xa0
[000000000074c1dc] driver_attach+0x1c/0x40
[000000000074b0fc] bus_add_driver+0xbc/0x280
Signed-off-by: Sowmini Varadhan <sowmini.varadhan@oracle.com>
Acked-by: Dwight Engen <dwight.engen@oracle.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/sparc/include/asm/ldc.h | 5 | ||||
-rw-r--r-- | arch/sparc/kernel/ds.c | 4 | ||||
-rw-r--r-- | arch/sparc/kernel/ldc.c | 41 | ||||
-rw-r--r-- | arch/sparc/kernel/viohs.c | 4 |
4 files changed, 28 insertions, 26 deletions
diff --git a/arch/sparc/include/asm/ldc.h b/arch/sparc/include/asm/ldc.h index c8c67f621f4f..58ab64de25d2 100644 --- a/arch/sparc/include/asm/ldc.h +++ b/arch/sparc/include/asm/ldc.h | |||
@@ -53,13 +53,14 @@ struct ldc_channel; | |||
53 | /* Allocate state for a channel. */ | 53 | /* Allocate state for a channel. */ |
54 | struct ldc_channel *ldc_alloc(unsigned long id, | 54 | struct ldc_channel *ldc_alloc(unsigned long id, |
55 | const struct ldc_channel_config *cfgp, | 55 | const struct ldc_channel_config *cfgp, |
56 | void *event_arg); | 56 | void *event_arg, |
57 | const char *name); | ||
57 | 58 | ||
58 | /* Shut down and free state for a channel. */ | 59 | /* Shut down and free state for a channel. */ |
59 | void ldc_free(struct ldc_channel *lp); | 60 | void ldc_free(struct ldc_channel *lp); |
60 | 61 | ||
61 | /* Register TX and RX queues of the link with the hypervisor. */ | 62 | /* Register TX and RX queues of the link with the hypervisor. */ |
62 | int ldc_bind(struct ldc_channel *lp, const char *name); | 63 | int ldc_bind(struct ldc_channel *lp); |
63 | 64 | ||
64 | /* For non-RAW protocols we need to complete a handshake before | 65 | /* For non-RAW protocols we need to complete a handshake before |
65 | * communication can proceed. ldc_connect() does that, if the | 66 | * communication can proceed. ldc_connect() does that, if the |
diff --git a/arch/sparc/kernel/ds.c b/arch/sparc/kernel/ds.c index dff60abbea01..f87a55d77094 100644 --- a/arch/sparc/kernel/ds.c +++ b/arch/sparc/kernel/ds.c | |||
@@ -1200,14 +1200,14 @@ static int ds_probe(struct vio_dev *vdev, const struct vio_device_id *id) | |||
1200 | ds_cfg.tx_irq = vdev->tx_irq; | 1200 | ds_cfg.tx_irq = vdev->tx_irq; |
1201 | ds_cfg.rx_irq = vdev->rx_irq; | 1201 | ds_cfg.rx_irq = vdev->rx_irq; |
1202 | 1202 | ||
1203 | lp = ldc_alloc(vdev->channel_id, &ds_cfg, dp); | 1203 | lp = ldc_alloc(vdev->channel_id, &ds_cfg, dp, "DS"); |
1204 | if (IS_ERR(lp)) { | 1204 | if (IS_ERR(lp)) { |
1205 | err = PTR_ERR(lp); | 1205 | err = PTR_ERR(lp); |
1206 | goto out_free_ds_states; | 1206 | goto out_free_ds_states; |
1207 | } | 1207 | } |
1208 | dp->lp = lp; | 1208 | dp->lp = lp; |
1209 | 1209 | ||
1210 | err = ldc_bind(lp, "DS"); | 1210 | err = ldc_bind(lp); |
1211 | if (err) | 1211 | if (err) |
1212 | goto out_free_ldc; | 1212 | goto out_free_ldc; |
1213 | 1213 | ||
diff --git a/arch/sparc/kernel/ldc.c b/arch/sparc/kernel/ldc.c index 66dacd56bb10..27bb55485472 100644 --- a/arch/sparc/kernel/ldc.c +++ b/arch/sparc/kernel/ldc.c | |||
@@ -1078,7 +1078,8 @@ static void ldc_iommu_release(struct ldc_channel *lp) | |||
1078 | 1078 | ||
1079 | struct ldc_channel *ldc_alloc(unsigned long id, | 1079 | struct ldc_channel *ldc_alloc(unsigned long id, |
1080 | const struct ldc_channel_config *cfgp, | 1080 | const struct ldc_channel_config *cfgp, |
1081 | void *event_arg) | 1081 | void *event_arg, |
1082 | const char *name) | ||
1082 | { | 1083 | { |
1083 | struct ldc_channel *lp; | 1084 | struct ldc_channel *lp; |
1084 | const struct ldc_mode_ops *mops; | 1085 | const struct ldc_mode_ops *mops; |
@@ -1093,6 +1094,8 @@ struct ldc_channel *ldc_alloc(unsigned long id, | |||
1093 | err = -EINVAL; | 1094 | err = -EINVAL; |
1094 | if (!cfgp) | 1095 | if (!cfgp) |
1095 | goto out_err; | 1096 | goto out_err; |
1097 | if (!name) | ||
1098 | goto out_err; | ||
1096 | 1099 | ||
1097 | switch (cfgp->mode) { | 1100 | switch (cfgp->mode) { |
1098 | case LDC_MODE_RAW: | 1101 | case LDC_MODE_RAW: |
@@ -1185,6 +1188,21 @@ struct ldc_channel *ldc_alloc(unsigned long id, | |||
1185 | 1188 | ||
1186 | INIT_HLIST_HEAD(&lp->mh_list); | 1189 | INIT_HLIST_HEAD(&lp->mh_list); |
1187 | 1190 | ||
1191 | snprintf(lp->rx_irq_name, LDC_IRQ_NAME_MAX, "%s RX", name); | ||
1192 | snprintf(lp->tx_irq_name, LDC_IRQ_NAME_MAX, "%s TX", name); | ||
1193 | |||
1194 | err = request_irq(lp->cfg.rx_irq, ldc_rx, 0, | ||
1195 | lp->rx_irq_name, lp); | ||
1196 | if (err) | ||
1197 | goto out_free_txq; | ||
1198 | |||
1199 | err = request_irq(lp->cfg.tx_irq, ldc_tx, 0, | ||
1200 | lp->tx_irq_name, lp); | ||
1201 | if (err) { | ||
1202 | free_irq(lp->cfg.rx_irq, lp); | ||
1203 | goto out_free_txq; | ||
1204 | } | ||
1205 | |||
1188 | return lp; | 1206 | return lp; |
1189 | 1207 | ||
1190 | out_free_txq: | 1208 | out_free_txq: |
@@ -1237,31 +1255,14 @@ EXPORT_SYMBOL(ldc_free); | |||
1237 | * state. This does not initiate a handshake, ldc_connect() does | 1255 | * state. This does not initiate a handshake, ldc_connect() does |
1238 | * that. | 1256 | * that. |
1239 | */ | 1257 | */ |
1240 | int ldc_bind(struct ldc_channel *lp, const char *name) | 1258 | int ldc_bind(struct ldc_channel *lp) |
1241 | { | 1259 | { |
1242 | unsigned long hv_err, flags; | 1260 | unsigned long hv_err, flags; |
1243 | int err = -EINVAL; | 1261 | int err = -EINVAL; |
1244 | 1262 | ||
1245 | if (!name || | 1263 | if (lp->state != LDC_STATE_INIT) |
1246 | (lp->state != LDC_STATE_INIT)) | ||
1247 | return -EINVAL; | 1264 | return -EINVAL; |
1248 | 1265 | ||
1249 | snprintf(lp->rx_irq_name, LDC_IRQ_NAME_MAX, "%s RX", name); | ||
1250 | snprintf(lp->tx_irq_name, LDC_IRQ_NAME_MAX, "%s TX", name); | ||
1251 | |||
1252 | err = request_irq(lp->cfg.rx_irq, ldc_rx, 0, | ||
1253 | lp->rx_irq_name, lp); | ||
1254 | if (err) | ||
1255 | return err; | ||
1256 | |||
1257 | err = request_irq(lp->cfg.tx_irq, ldc_tx, 0, | ||
1258 | lp->tx_irq_name, lp); | ||
1259 | if (err) { | ||
1260 | free_irq(lp->cfg.rx_irq, lp); | ||
1261 | return err; | ||
1262 | } | ||
1263 | |||
1264 | |||
1265 | spin_lock_irqsave(&lp->lock, flags); | 1266 | spin_lock_irqsave(&lp->lock, flags); |
1266 | 1267 | ||
1267 | enable_irq(lp->cfg.rx_irq); | 1268 | enable_irq(lp->cfg.rx_irq); |
diff --git a/arch/sparc/kernel/viohs.c b/arch/sparc/kernel/viohs.c index f8e7dd53e1c7..9c5fbd0b8a04 100644 --- a/arch/sparc/kernel/viohs.c +++ b/arch/sparc/kernel/viohs.c | |||
@@ -714,7 +714,7 @@ int vio_ldc_alloc(struct vio_driver_state *vio, | |||
714 | cfg.tx_irq = vio->vdev->tx_irq; | 714 | cfg.tx_irq = vio->vdev->tx_irq; |
715 | cfg.rx_irq = vio->vdev->rx_irq; | 715 | cfg.rx_irq = vio->vdev->rx_irq; |
716 | 716 | ||
717 | lp = ldc_alloc(vio->vdev->channel_id, &cfg, event_arg); | 717 | lp = ldc_alloc(vio->vdev->channel_id, &cfg, event_arg, vio->name); |
718 | if (IS_ERR(lp)) | 718 | if (IS_ERR(lp)) |
719 | return PTR_ERR(lp); | 719 | return PTR_ERR(lp); |
720 | 720 | ||
@@ -746,7 +746,7 @@ void vio_port_up(struct vio_driver_state *vio) | |||
746 | 746 | ||
747 | err = 0; | 747 | err = 0; |
748 | if (state == LDC_STATE_INIT) { | 748 | if (state == LDC_STATE_INIT) { |
749 | err = ldc_bind(vio->lp, vio->name); | 749 | err = ldc_bind(vio->lp); |
750 | if (err) | 750 | if (err) |
751 | printk(KERN_WARNING "%s: Port %lu bind failed, " | 751 | printk(KERN_WARNING "%s: Port %lu bind failed, " |
752 | "err=%d\n", | 752 | "err=%d\n", |