Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'for-3.16-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata

Pull libata regression fix from Tejun Heo:
"The last libata/for-3.16-fixes pull contained a regression introduced
by 1871ee134b73 ("libata: support the ata host which implements a
queue depth less than 32") which in turn was a fix for a regression
introduced earlier while changing queue tag order to accomodate hard
drives which perform poorly if tags are not allocated in circular
order (ugh...).

The regression happens only for SAS controllers making use of libata
to serve ATA devices. They don't fill an ata_host field which is used
by the new tag allocation function leading to NULL dereference.

This patch adds a new intermediate field ata_host->n_tags which is
initialized for both SAS and !SAS cases to fix the issue"

* 'for-3.16-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata:
libata: introduce ata_host->n_tags to avoid oops on SAS controllers

+5 -12
+4 -12
drivers/ata/libata-core.c
··· 4798 4798 static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap) 4799 4799 { 4800 4800 struct ata_queued_cmd *qc = NULL; 4801 - unsigned int i, tag, max_queue; 4802 - 4803 - max_queue = ap->scsi_host->can_queue; 4801 + unsigned int max_queue = ap->host->n_tags; 4802 + unsigned int i, tag; 4804 4803 4805 4804 /* no command while frozen */ 4806 4805 if (unlikely(ap->pflags & ATA_PFLAG_FROZEN)) ··· 6093 6094 { 6094 6095 spin_lock_init(&host->lock); 6095 6096 mutex_init(&host->eh_mutex); 6097 + host->n_tags = ATA_MAX_QUEUE - 1; 6096 6098 host->dev = dev; 6097 6099 host->ops = ops; 6098 6100 } ··· 6175 6175 { 6176 6176 int i, rc; 6177 6177 6178 - /* 6179 - * The max queue supported by hardware must not be greater than 6180 - * ATA_MAX_QUEUE. 6181 - */ 6182 - if (sht->can_queue > ATA_MAX_QUEUE) { 6183 - dev_err(host->dev, "BUG: the hardware max queue is too large\n"); 6184 - WARN_ON(1); 6185 - return -EINVAL; 6186 - } 6178 + host->n_tags = clamp(sht->can_queue, 1, ATA_MAX_QUEUE - 1); 6187 6179 6188 6180 /* host must have been started */ 6189 6181 if (!(host->flags & ATA_HOST_STARTED)) {
+1
include/linux/libata.h
··· 593 593 struct device *dev; 594 594 void __iomem * const *iomap; 595 595 unsigned int n_ports; 596 + unsigned int n_tags; /* nr of NCQ tags */ 596 597 void *private_data; 597 598 struct ata_port_operations *ops; 598 599 unsigned long flags;