Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 26645
b: refs/heads/master
c: 6572b20
h: refs/heads/master
i:
  26643: b559796
v: v3
  • Loading branch information
Linus Torvalds committed May 11, 2006
1 parent e22471e commit 160c2f0
Show file tree
Hide file tree
Showing 50 changed files with 903 additions and 542 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 210525d65d33d17eb6bea6c965ce442d60d9aa8d
refs/heads/master: 6572b2064a54f1ed29fcbf6d16dfc5de71dfe495
25 changes: 25 additions & 0 deletions trunk/Documentation/scsi/ChangeLog.megaraid
Original file line number Diff line number Diff line change
@@ -1,3 +1,28 @@
Release Date : Mon Apr 11 12:27:22 EST 2006 - Seokmann Ju <sju@lsil.com>
Current Version : 2.20.4.8 (scsi module), 2.20.2.6 (cmm module)
Older Version : 2.20.4.7 (scsi module), 2.20.2.6 (cmm module)

1. Fixed a bug in megaraid_reset_handler().
Customer reported "Unable to handle kernel NULL pointer dereference
at virtual address 00000000" when system goes to reset condition
for some reason. It happened randomly.
Root Cause: in the megaraid_reset_handler(), there is possibility not
returning pending packets in the pend_list if there are multiple
pending packets.
Fix: Made the change in the driver so that it will return all packets
in the pend_list.

2. Added change request.
As found in the following URL, rmb() only didn't help the
problem. I had to increase the loop counter to 0xFFFFFF. (6 F's)
http://marc.theaimsgroup.com/?l=linux-scsi&m=110971060502497&w=2

I attached a patch for your reference, too.
Could you check and get this fix in your driver?

Best Regards,
Jun'ichi Nomura

Release Date : Fri Nov 11 12:27:22 EST 2005 - Seokmann Ju <sju@lsil.com>
Current Version : 2.20.4.7 (scsi module), 2.20.2.6 (cmm module)
Older Version : 2.20.4.6 (scsi module), 2.20.2.6 (cmm module)
Expand Down
8 changes: 7 additions & 1 deletion trunk/block/elevator.c
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,7 @@ void elv_insert(request_queue_t *q, struct request *rq, int where)
{
struct list_head *pos;
unsigned ordseq;
int unplug_it = 1;

blk_add_trace_rq(q, rq, BLK_TA_INSERT);

Expand Down Expand Up @@ -399,6 +400,11 @@ void elv_insert(request_queue_t *q, struct request *rq, int where)
}

list_add_tail(&rq->queuelist, pos);
/*
* most requeues happen because of a busy condition, don't
* force unplug of the queue for that case.
*/
unplug_it = 0;
break;

default:
Expand All @@ -407,7 +413,7 @@ void elv_insert(request_queue_t *q, struct request *rq, int where)
BUG();
}

if (blk_queue_plugged(q)) {
if (unplug_it && blk_queue_plugged(q)) {
int nrq = q->rq.count[READ] + q->rq.count[WRITE]
- q->in_flight;

Expand Down
17 changes: 15 additions & 2 deletions trunk/block/ll_rw_blk.c
Original file line number Diff line number Diff line change
Expand Up @@ -1732,8 +1732,21 @@ void blk_run_queue(struct request_queue *q)

spin_lock_irqsave(q->queue_lock, flags);
blk_remove_plug(q);
if (!elv_queue_empty(q))
q->request_fn(q);

/*
* Only recurse once to avoid overrunning the stack, let the unplug
* handling reinvoke the handler shortly if we already got there.
*/
if (!elv_queue_empty(q)) {
if (!test_and_set_bit(QUEUE_FLAG_REENTER, &q->queue_flags)) {
q->request_fn(q);
clear_bit(QUEUE_FLAG_REENTER, &q->queue_flags);
} else {
blk_plug_device(q);
kblockd_schedule_work(&q->unplug_work);
}
}

spin_unlock_irqrestore(q->queue_lock, flags);
}
EXPORT_SYMBOL(blk_run_queue);
Expand Down
10 changes: 6 additions & 4 deletions trunk/drivers/char/pcmcia/cm4000_cs.c
Original file line number Diff line number Diff line change
Expand Up @@ -1981,17 +1981,19 @@ static int __init cmm_init(void)
if (!cmm_class)
return -1;

rc = pcmcia_register_driver(&cm4000_driver);
if (rc < 0)
return rc;

major = register_chrdev(0, DEVICE_NAME, &cm4000_fops);
if (major < 0) {
printk(KERN_WARNING MODULE_NAME
": could not get major number\n");
return -1;
}

rc = pcmcia_register_driver(&cm4000_driver);
if (rc < 0) {
unregister_chrdev(major, DEVICE_NAME);
return rc;
}

return 0;
}

Expand Down
11 changes: 7 additions & 4 deletions trunk/drivers/char/pcmcia/cm4040_cs.c
Original file line number Diff line number Diff line change
Expand Up @@ -724,16 +724,19 @@ static int __init cm4040_init(void)
if (!cmx_class)
return -1;

rc = pcmcia_register_driver(&reader_driver);
if (rc < 0)
return rc;

major = register_chrdev(0, DEVICE_NAME, &reader_fops);
if (major < 0) {
printk(KERN_WARNING MODULE_NAME
": could not get major number\n");
return -1;
}

rc = pcmcia_register_driver(&reader_driver);
if (rc < 0) {
unregister_chrdev(major, DEVICE_NAME);
return rc;
}

return 0;
}

Expand Down
2 changes: 1 addition & 1 deletion trunk/drivers/infiniband/core/sysfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ static ssize_t show_pma_counter(struct ib_port *p, struct port_attribute *attr,
switch (width) {
case 4:
ret = sprintf(buf, "%u\n", (out_mad->data[40 + offset / 8] >>
(offset % 4)) & 0xf);
(4 - (offset % 8))) & 0xf);
break;
case 8:
ret = sprintf(buf, "%u\n", out_mad->data[40 + offset / 8]);
Expand Down
41 changes: 21 additions & 20 deletions trunk/drivers/infiniband/hw/mthca/mthca_cq.c
Original file line number Diff line number Diff line change
Expand Up @@ -238,9 +238,9 @@ void mthca_cq_event(struct mthca_dev *dev, u32 cqn,
spin_lock(&dev->cq_table.lock);

cq = mthca_array_get(&dev->cq_table.cq, cqn & (dev->limits.num_cqs - 1));

if (cq)
atomic_inc(&cq->refcount);
++cq->refcount;

spin_unlock(&dev->cq_table.lock);

if (!cq) {
Expand All @@ -254,8 +254,10 @@ void mthca_cq_event(struct mthca_dev *dev, u32 cqn,
if (cq->ibcq.event_handler)
cq->ibcq.event_handler(&event, cq->ibcq.cq_context);

if (atomic_dec_and_test(&cq->refcount))
spin_lock(&dev->cq_table.lock);
if (!--cq->refcount)
wake_up(&cq->wait);
spin_unlock(&dev->cq_table.lock);
}

static inline int is_recv_cqe(struct mthca_cqe *cqe)
Expand All @@ -267,23 +269,13 @@ static inline int is_recv_cqe(struct mthca_cqe *cqe)
return !(cqe->is_send & 0x80);
}

void mthca_cq_clean(struct mthca_dev *dev, u32 cqn, u32 qpn,
void mthca_cq_clean(struct mthca_dev *dev, struct mthca_cq *cq, u32 qpn,
struct mthca_srq *srq)
{
struct mthca_cq *cq;
struct mthca_cqe *cqe;
u32 prod_index;
int nfreed = 0;

spin_lock_irq(&dev->cq_table.lock);
cq = mthca_array_get(&dev->cq_table.cq, cqn & (dev->limits.num_cqs - 1));
if (cq)
atomic_inc(&cq->refcount);
spin_unlock_irq(&dev->cq_table.lock);

if (!cq)
return;

spin_lock_irq(&cq->lock);

/*
Expand All @@ -301,7 +293,7 @@ void mthca_cq_clean(struct mthca_dev *dev, u32 cqn, u32 qpn,

if (0)
mthca_dbg(dev, "Cleaning QPN %06x from CQN %06x; ci %d, pi %d\n",
qpn, cqn, cq->cons_index, prod_index);
qpn, cq->cqn, cq->cons_index, prod_index);

/*
* Now sweep backwards through the CQ, removing CQ entries
Expand All @@ -325,8 +317,6 @@ void mthca_cq_clean(struct mthca_dev *dev, u32 cqn, u32 qpn,
}

spin_unlock_irq(&cq->lock);
if (atomic_dec_and_test(&cq->refcount))
wake_up(&cq->wait);
}

void mthca_cq_resize_copy_cqes(struct mthca_cq *cq)
Expand Down Expand Up @@ -821,7 +811,7 @@ int mthca_init_cq(struct mthca_dev *dev, int nent,
}

spin_lock_init(&cq->lock);
atomic_set(&cq->refcount, 1);
cq->refcount = 1;
init_waitqueue_head(&cq->wait);

memset(cq_context, 0, sizeof *cq_context);
Expand Down Expand Up @@ -896,6 +886,17 @@ int mthca_init_cq(struct mthca_dev *dev, int nent,
return err;
}

static inline int get_cq_refcount(struct mthca_dev *dev, struct mthca_cq *cq)
{
int c;

spin_lock_irq(&dev->cq_table.lock);
c = cq->refcount;
spin_unlock_irq(&dev->cq_table.lock);

return c;
}

void mthca_free_cq(struct mthca_dev *dev,
struct mthca_cq *cq)
{
Expand Down Expand Up @@ -929,15 +930,15 @@ void mthca_free_cq(struct mthca_dev *dev,
spin_lock_irq(&dev->cq_table.lock);
mthca_array_clear(&dev->cq_table.cq,
cq->cqn & (dev->limits.num_cqs - 1));
--cq->refcount;
spin_unlock_irq(&dev->cq_table.lock);

if (dev->mthca_flags & MTHCA_FLAG_MSI_X)
synchronize_irq(dev->eq_table.eq[MTHCA_EQ_COMP].msi_x_vector);
else
synchronize_irq(dev->pdev->irq);

atomic_dec(&cq->refcount);
wait_event(cq->wait, !atomic_read(&cq->refcount));
wait_event(cq->wait, !get_cq_refcount(dev, cq));

if (cq->is_kernel) {
mthca_free_cq_buf(dev, &cq->buf, cq->ibcq.cqe);
Expand Down
2 changes: 1 addition & 1 deletion trunk/drivers/infiniband/hw/mthca/mthca_dev.h
Original file line number Diff line number Diff line change
Expand Up @@ -496,7 +496,7 @@ void mthca_free_cq(struct mthca_dev *dev,
void mthca_cq_completion(struct mthca_dev *dev, u32 cqn);
void mthca_cq_event(struct mthca_dev *dev, u32 cqn,
enum ib_event_type event_type);
void mthca_cq_clean(struct mthca_dev *dev, u32 cqn, u32 qpn,
void mthca_cq_clean(struct mthca_dev *dev, struct mthca_cq *cq, u32 qpn,
struct mthca_srq *srq);
void mthca_cq_resize_copy_cqes(struct mthca_cq *cq);
int mthca_alloc_cq_buf(struct mthca_dev *dev, struct mthca_cq_buf *buf, int nent);
Expand Down
15 changes: 11 additions & 4 deletions trunk/drivers/infiniband/hw/mthca/mthca_mr.c
Original file line number Diff line number Diff line change
Expand Up @@ -761,6 +761,7 @@ void mthca_arbel_fmr_unmap(struct mthca_dev *dev, struct mthca_fmr *fmr)

int __devinit mthca_init_mr_table(struct mthca_dev *dev)
{
unsigned long addr;
int err, i;

err = mthca_alloc_init(&dev->mr_table.mpt_alloc,
Expand Down Expand Up @@ -796,19 +797,25 @@ int __devinit mthca_init_mr_table(struct mthca_dev *dev)
goto err_fmr_mpt;
}

addr = pci_resource_start(dev->pdev, 4) +
((pci_resource_len(dev->pdev, 4) - 1) &
dev->mr_table.mpt_base);

dev->mr_table.tavor_fmr.mpt_base =
ioremap(dev->mr_table.mpt_base,
(1 << i) * sizeof (struct mthca_mpt_entry));
ioremap(addr, (1 << i) * sizeof(struct mthca_mpt_entry));

if (!dev->mr_table.tavor_fmr.mpt_base) {
mthca_warn(dev, "MPT ioremap for FMR failed.\n");
err = -ENOMEM;
goto err_fmr_mpt;
}

addr = pci_resource_start(dev->pdev, 4) +
((pci_resource_len(dev->pdev, 4) - 1) &
dev->mr_table.mtt_base);

dev->mr_table.tavor_fmr.mtt_base =
ioremap(dev->mr_table.mtt_base,
(1 << i) * MTHCA_MTT_SEG_SIZE);
ioremap(addr, (1 << i) * MTHCA_MTT_SEG_SIZE);
if (!dev->mr_table.tavor_fmr.mtt_base) {
mthca_warn(dev, "MTT ioremap for FMR failed.\n");
err = -ENOMEM;
Expand Down
22 changes: 12 additions & 10 deletions trunk/drivers/infiniband/hw/mthca/mthca_provider.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,11 +139,12 @@ struct mthca_ah {
* a qp may be locked, with the send cq locked first. No other
* nesting should be done.
*
* Each struct mthca_cq/qp also has an atomic_t ref count. The
* pointer from the cq/qp_table to the struct counts as one reference.
* This reference also is good for access through the consumer API, so
* modifying the CQ/QP etc doesn't need to take another reference.
* Access because of a completion being polled does need a reference.
* Each struct mthca_cq/qp also has an ref count, protected by the
* corresponding table lock. The pointer from the cq/qp_table to the
* struct counts as one reference. This reference also is good for
* access through the consumer API, so modifying the CQ/QP etc doesn't
* need to take another reference. Access to a QP because of a
* completion being polled does not need a reference either.
*
* Finally, each struct mthca_cq/qp has a wait_queue_head_t for the
* destroy function to sleep on.
Expand All @@ -159,8 +160,9 @@ struct mthca_ah {
* - decrement ref count; if zero, wake up waiters
*
* To destroy a CQ/QP, we can do the following:
* - lock cq/qp_table, remove pointer, unlock cq/qp_table lock
* - decrement ref count
* - lock cq/qp_table
* - remove pointer and decrement ref count
* - unlock cq/qp_table lock
* - wait_event until ref count is zero
*
* It is the consumer's responsibilty to make sure that no QP
Expand Down Expand Up @@ -197,7 +199,7 @@ struct mthca_cq_resize {
struct mthca_cq {
struct ib_cq ibcq;
spinlock_t lock;
atomic_t refcount;
int refcount;
int cqn;
u32 cons_index;
struct mthca_cq_buf buf;
Expand All @@ -217,7 +219,7 @@ struct mthca_cq {
struct mthca_srq {
struct ib_srq ibsrq;
spinlock_t lock;
atomic_t refcount;
int refcount;
int srqn;
int max;
int max_gs;
Expand Down Expand Up @@ -254,7 +256,7 @@ struct mthca_wq {

struct mthca_qp {
struct ib_qp ibqp;
atomic_t refcount;
int refcount;
u32 qpn;
int is_direct;
u8 port; /* for SQP and memfree use only */
Expand Down
Loading

0 comments on commit 160c2f0

Please sign in to comment.