Skip to content

Commit

Permalink
block: IBM RamSan 70/80 fixes inconsistent locking.
Browse files Browse the repository at this point in the history
This patch includes changes to the cregs locking scheme. Before,
inconsistant locking would occur because of misuse of spin_lock,
spin_lock_bh, and counter parts.

Signed-off-by: Philip J Kelleher <pjk1939@linux.vnet.ibm.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
  • Loading branch information
Philip J Kelleher authored and Jens Axboe committed Mar 11, 2013
1 parent f379120 commit 03ac03a
Showing 1 changed file with 18 additions and 26 deletions.
44 changes: 18 additions & 26 deletions drivers/block/rsxx/cregs.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,22 +99,6 @@ static void copy_from_creg_data(struct rsxx_cardinfo *card,
}
}

static struct creg_cmd *pop_active_cmd(struct rsxx_cardinfo *card)
{
struct creg_cmd *cmd;

/*
* Spin lock is needed because this can be called in atomic/interrupt
* context.
*/
spin_lock_bh(&card->creg_ctrl.lock);
cmd = card->creg_ctrl.active_cmd;
card->creg_ctrl.active_cmd = NULL;
spin_unlock_bh(&card->creg_ctrl.lock);

return cmd;
}

static void creg_issue_cmd(struct rsxx_cardinfo *card, struct creg_cmd *cmd)
{
iowrite32(cmd->addr, card->regmap + CREG_ADD);
Expand Down Expand Up @@ -189,11 +173,11 @@ static int creg_queue_cmd(struct rsxx_cardinfo *card,
cmd->cb_private = cb_private;
cmd->status = 0;

spin_lock(&card->creg_ctrl.lock);
spin_lock_bh(&card->creg_ctrl.lock);
list_add_tail(&cmd->list, &card->creg_ctrl.queue);
card->creg_ctrl.q_depth++;
creg_kick_queue(card);
spin_unlock(&card->creg_ctrl.lock);
spin_unlock_bh(&card->creg_ctrl.lock);

return 0;
}
Expand All @@ -203,7 +187,11 @@ static void creg_cmd_timed_out(unsigned long data)
struct rsxx_cardinfo *card = (struct rsxx_cardinfo *) data;
struct creg_cmd *cmd;

cmd = pop_active_cmd(card);
spin_lock(&card->creg_ctrl.lock);
cmd = card->creg_ctrl.active_cmd;
card->creg_ctrl.active_cmd = NULL;
spin_unlock(&card->creg_ctrl.lock);

if (cmd == NULL) {
card->creg_ctrl.creg_stats.creg_timeout++;
dev_warn(CARD_TO_DEV(card),
Expand Down Expand Up @@ -240,7 +228,11 @@ static void creg_cmd_done(struct work_struct *work)
if (del_timer_sync(&card->creg_ctrl.cmd_timer) == 0)
card->creg_ctrl.creg_stats.failed_cancel_timer++;

cmd = pop_active_cmd(card);
spin_lock_bh(&card->creg_ctrl.lock);
cmd = card->creg_ctrl.active_cmd;
card->creg_ctrl.active_cmd = NULL;
spin_unlock_bh(&card->creg_ctrl.lock);

if (cmd == NULL) {
dev_err(CARD_TO_DEV(card),
"Spurious creg interrupt!\n");
Expand Down Expand Up @@ -289,10 +281,10 @@ static void creg_cmd_done(struct work_struct *work)

kmem_cache_free(creg_cmd_pool, cmd);

spin_lock(&card->creg_ctrl.lock);
spin_lock_bh(&card->creg_ctrl.lock);
card->creg_ctrl.active = 0;
creg_kick_queue(card);
spin_unlock(&card->creg_ctrl.lock);
spin_unlock_bh(&card->creg_ctrl.lock);
}

static void creg_reset(struct rsxx_cardinfo *card)
Expand All @@ -317,7 +309,7 @@ static void creg_reset(struct rsxx_cardinfo *card)
"Resetting creg interface for recovery\n");

/* Cancel outstanding commands */
spin_lock(&card->creg_ctrl.lock);
spin_lock_bh(&card->creg_ctrl.lock);
list_for_each_entry_safe(cmd, tmp, &card->creg_ctrl.queue, list) {
list_del(&cmd->list);
card->creg_ctrl.q_depth--;
Expand All @@ -338,7 +330,7 @@ static void creg_reset(struct rsxx_cardinfo *card)

card->creg_ctrl.active = 0;
}
spin_unlock(&card->creg_ctrl.lock);
spin_unlock_bh(&card->creg_ctrl.lock);

card->creg_ctrl.reset = 0;
spin_lock_irqsave(&card->irq_lock, flags);
Expand Down Expand Up @@ -705,7 +697,7 @@ void rsxx_creg_destroy(struct rsxx_cardinfo *card)
int cnt = 0;

/* Cancel outstanding commands */
spin_lock(&card->creg_ctrl.lock);
spin_lock_bh(&card->creg_ctrl.lock);
list_for_each_entry_safe(cmd, tmp, &card->creg_ctrl.queue, list) {
list_del(&cmd->list);
if (cmd->cb)
Expand All @@ -730,7 +722,7 @@ void rsxx_creg_destroy(struct rsxx_cardinfo *card)
"Canceled active creg command\n");
kmem_cache_free(creg_cmd_pool, cmd);
}
spin_unlock(&card->creg_ctrl.lock);
spin_unlock_bh(&card->creg_ctrl.lock);

cancel_work_sync(&card->creg_ctrl.done_work);
}
Expand Down

0 comments on commit 03ac03a

Please sign in to comment.