lkml.org 
[lkml]   [2014]   [Oct]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 3.17 124/146] sparc64: Move request_irq() from ldc_bind() to ldc_alloc()
    Date
    3.17-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Sowmini Varadhan <sowmini.varadhan@oracle.com>

    [ Upstream commit c21c4ab0d6921f7160a43216fa6973b5924de561 ]

    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>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    arch/sparc/include/asm/ldc.h | 5 +++--
    arch/sparc/kernel/ds.c | 4 ++--
    arch/sparc/kernel/ldc.c | 41 +++++++++++++++++++++--------------------
    arch/sparc/kernel/viohs.c | 4 ++--
    4 files changed, 28 insertions(+), 26 deletions(-)

    --- a/arch/sparc/include/asm/ldc.h
    +++ b/arch/sparc/include/asm/ldc.h
    @@ -53,13 +53,14 @@ struct ldc_channel;
    /* Allocate state for a channel. */
    struct ldc_channel *ldc_alloc(unsigned long id,
    const struct ldc_channel_config *cfgp,
    - void *event_arg);
    + void *event_arg,
    + const char *name);

    /* Shut down and free state for a channel. */
    void ldc_free(struct ldc_channel *lp);

    /* Register TX and RX queues of the link with the hypervisor. */
    -int ldc_bind(struct ldc_channel *lp, const char *name);
    +int ldc_bind(struct ldc_channel *lp);

    /* For non-RAW protocols we need to complete a handshake before
    * communication can proceed. ldc_connect() does that, if the
    --- a/arch/sparc/kernel/ds.c
    +++ b/arch/sparc/kernel/ds.c
    @@ -1200,14 +1200,14 @@ static int ds_probe(struct vio_dev *vdev
    ds_cfg.tx_irq = vdev->tx_irq;
    ds_cfg.rx_irq = vdev->rx_irq;

    - lp = ldc_alloc(vdev->channel_id, &ds_cfg, dp);
    + lp = ldc_alloc(vdev->channel_id, &ds_cfg, dp, "DS");
    if (IS_ERR(lp)) {
    err = PTR_ERR(lp);
    goto out_free_ds_states;
    }
    dp->lp = lp;

    - err = ldc_bind(lp, "DS");
    + err = ldc_bind(lp);
    if (err)
    goto out_free_ldc;

    --- a/arch/sparc/kernel/ldc.c
    +++ b/arch/sparc/kernel/ldc.c
    @@ -1078,7 +1078,8 @@ static void ldc_iommu_release(struct ldc

    struct ldc_channel *ldc_alloc(unsigned long id,
    const struct ldc_channel_config *cfgp,
    - void *event_arg)
    + void *event_arg,
    + const char *name)
    {
    struct ldc_channel *lp;
    const struct ldc_mode_ops *mops;
    @@ -1093,6 +1094,8 @@ struct ldc_channel *ldc_alloc(unsigned l
    err = -EINVAL;
    if (!cfgp)
    goto out_err;
    + if (!name)
    + goto out_err;

    switch (cfgp->mode) {
    case LDC_MODE_RAW:
    @@ -1185,6 +1188,21 @@ struct ldc_channel *ldc_alloc(unsigned l

    INIT_HLIST_HEAD(&lp->mh_list);

    + snprintf(lp->rx_irq_name, LDC_IRQ_NAME_MAX, "%s RX", name);
    + snprintf(lp->tx_irq_name, LDC_IRQ_NAME_MAX, "%s TX", name);
    +
    + err = request_irq(lp->cfg.rx_irq, ldc_rx, 0,
    + lp->rx_irq_name, lp);
    + if (err)
    + goto out_free_txq;
    +
    + err = request_irq(lp->cfg.tx_irq, ldc_tx, 0,
    + lp->tx_irq_name, lp);
    + if (err) {
    + free_irq(lp->cfg.rx_irq, lp);
    + goto out_free_txq;
    + }
    +
    return lp;

    out_free_txq:
    @@ -1237,31 +1255,14 @@ EXPORT_SYMBOL(ldc_free);
    * state. This does not initiate a handshake, ldc_connect() does
    * that.
    */
    -int ldc_bind(struct ldc_channel *lp, const char *name)
    +int ldc_bind(struct ldc_channel *lp)
    {
    unsigned long hv_err, flags;
    int err = -EINVAL;

    - if (!name ||
    - (lp->state != LDC_STATE_INIT))
    + if (lp->state != LDC_STATE_INIT)
    return -EINVAL;

    - snprintf(lp->rx_irq_name, LDC_IRQ_NAME_MAX, "%s RX", name);
    - snprintf(lp->tx_irq_name, LDC_IRQ_NAME_MAX, "%s TX", name);
    -
    - err = request_irq(lp->cfg.rx_irq, ldc_rx, 0,
    - lp->rx_irq_name, lp);
    - if (err)
    - return err;
    -
    - err = request_irq(lp->cfg.tx_irq, ldc_tx, 0,
    - lp->tx_irq_name, lp);
    - if (err) {
    - free_irq(lp->cfg.rx_irq, lp);
    - return err;
    - }
    -
    -
    spin_lock_irqsave(&lp->lock, flags);

    enable_irq(lp->cfg.rx_irq);
    --- a/arch/sparc/kernel/viohs.c
    +++ b/arch/sparc/kernel/viohs.c
    @@ -714,7 +714,7 @@ int vio_ldc_alloc(struct vio_driver_stat
    cfg.tx_irq = vio->vdev->tx_irq;
    cfg.rx_irq = vio->vdev->rx_irq;

    - lp = ldc_alloc(vio->vdev->channel_id, &cfg, event_arg);
    + lp = ldc_alloc(vio->vdev->channel_id, &cfg, event_arg, vio->name);
    if (IS_ERR(lp))
    return PTR_ERR(lp);

    @@ -746,7 +746,7 @@ void vio_port_up(struct vio_driver_state

    err = 0;
    if (state == LDC_STATE_INIT) {
    - err = ldc_bind(vio->lp, vio->name);
    + err = ldc_bind(vio->lp);
    if (err)
    printk(KERN_WARNING "%s: Port %lu bind failed, "
    "err=%d\n",



    \
     
     \ /
      Last update: 2014-10-28 05:01    [W:4.108 / U:0.028 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site