lkml.org 
[lkml]   [2012]   [Feb]   [1]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[78/89] rds: Make rds_sock_lock BH rather than IRQ safe.
    3.2-stable review patch.  If anyone has any objections, please let me know.

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


    From: "David S. Miller" <davem@davemloft.net>

    [ Upstream commit efc3dbc37412c027e363736b4f4c74ee5e8ecffc ]

    rds_sock_info() triggers locking warnings because we try to perform a
    local_bh_enable() (via sock_i_ino()) while hardware interrupts are
    disabled (via taking rds_sock_lock).

    There is no reason for rds_sock_lock to be a hardware IRQ disabling
    lock, none of these access paths run in hardware interrupt context.

    Therefore making it a BH disabling lock is safe and sufficient to
    fix this bug.

    Reported-by: Kumar Sanghvi <kumaras@chelsio.com>
    Reported-by: Josh Boyer <jwboyer@gmail.com>
    Signed-off-by: David S. Miller <davem@davemloft.net>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    net/rds/af_rds.c | 20 ++++++++------------
    1 file changed, 8 insertions(+), 12 deletions(-)

    --- a/net/rds/af_rds.c
    +++ b/net/rds/af_rds.c
    @@ -68,7 +68,6 @@ static int rds_release(struct socket *so
    {
    struct sock *sk = sock->sk;
    struct rds_sock *rs;
    - unsigned long flags;

    if (!sk)
    goto out;
    @@ -94,10 +93,10 @@ static int rds_release(struct socket *so
    rds_rdma_drop_keys(rs);
    rds_notify_queue_get(rs, NULL);

    - spin_lock_irqsave(&rds_sock_lock, flags);
    + spin_lock_bh(&rds_sock_lock);
    list_del_init(&rs->rs_item);
    rds_sock_count--;
    - spin_unlock_irqrestore(&rds_sock_lock, flags);
    + spin_unlock_bh(&rds_sock_lock);

    rds_trans_put(rs->rs_transport);

    @@ -409,7 +408,6 @@ static const struct proto_ops rds_proto_

    static int __rds_create(struct socket *sock, struct sock *sk, int protocol)
    {
    - unsigned long flags;
    struct rds_sock *rs;

    sock_init_data(sock, sk);
    @@ -426,10 +424,10 @@ static int __rds_create(struct socket *s
    spin_lock_init(&rs->rs_rdma_lock);
    rs->rs_rdma_keys = RB_ROOT;

    - spin_lock_irqsave(&rds_sock_lock, flags);
    + spin_lock_bh(&rds_sock_lock);
    list_add_tail(&rs->rs_item, &rds_sock_list);
    rds_sock_count++;
    - spin_unlock_irqrestore(&rds_sock_lock, flags);
    + spin_unlock_bh(&rds_sock_lock);

    return 0;
    }
    @@ -471,12 +469,11 @@ static void rds_sock_inc_info(struct soc
    {
    struct rds_sock *rs;
    struct rds_incoming *inc;
    - unsigned long flags;
    unsigned int total = 0;

    len /= sizeof(struct rds_info_message);

    - spin_lock_irqsave(&rds_sock_lock, flags);
    + spin_lock_bh(&rds_sock_lock);

    list_for_each_entry(rs, &rds_sock_list, rs_item) {
    read_lock(&rs->rs_recv_lock);
    @@ -492,7 +489,7 @@ static void rds_sock_inc_info(struct soc
    read_unlock(&rs->rs_recv_lock);
    }

    - spin_unlock_irqrestore(&rds_sock_lock, flags);
    + spin_unlock_bh(&rds_sock_lock);

    lens->nr = total;
    lens->each = sizeof(struct rds_info_message);
    @@ -504,11 +501,10 @@ static void rds_sock_info(struct socket
    {
    struct rds_info_socket sinfo;
    struct rds_sock *rs;
    - unsigned long flags;

    len /= sizeof(struct rds_info_socket);

    - spin_lock_irqsave(&rds_sock_lock, flags);
    + spin_lock_bh(&rds_sock_lock);

    if (len < rds_sock_count)
    goto out;
    @@ -529,7 +525,7 @@ out:
    lens->nr = rds_sock_count;
    lens->each = sizeof(struct rds_info_socket);

    - spin_unlock_irqrestore(&rds_sock_lock, flags);
    + spin_unlock_bh(&rds_sock_lock);
    }

    static void rds_exit(void)



    \
     
     \ /
      Last update: 2012-02-01 22:15    [W:0.025 / U:0.892 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site