Re: [PATCH] incremental fix for NIU MSI-X problem

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Michael Ellerman wrote:
> On Fri, 2009-05-15 at 09:49 +0900, Hidetoshi Seto wrote:
>> It is definitely cleanup, not for NIU MSI-X problem, and not for .30
>>
>> One point...
>>
>> Matthew Wilcox wrote:
>>> +	nr_entries = msix_setup_entries(dev, pos, entries, nvec);
>>>  
>>>  	ret = arch_setup_msi_irqs(dev, nvec, PCI_CAP_ID_MSIX);
>>> -	if (ret < 0) {
>>> -		/* If we had some success report the number of irqs
>>> -		 * we succeeded in setting up. */
>>> -		int avail = 0;
>>> -		list_for_each_entry(entry, &dev->msi_list, list) {
>>> -			if (entry->irq != 0) {
>>> -				avail++;
>>> -			}
>>> -		}
>>> -
>>> -		if (avail != 0)
>>> -			ret = avail;
>>> -	}
>>> +	if (ret < 0 && nr_entries > 0)
>>> +		ret = nr_entries;
>>>  
>>>  	if (ret) {
>>>  		msi_free_irqs(dev);
>> I think this changes the logic badly.
>> nr_entries is number of allocated entry, while avail is number of irq
>> successfully allocated.  I suppose usually nr_entries > avail.
> 
> Yeah that bit's broken. If the arch routine fails (< 0) then we'll
> return nr_entries to the driver, which will then try again with nvec =
> nr_entries.
> 
> And you're passing nvec to the arch routine even though
> msix_setup_entries() might not have allocated that many entries - which
> means the value of nvec and the contents of the entry list don't match.

Hum, it seems it's an another bug.  Then we need fix like this?

--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -447,8 +447,10 @@ static int msix_capability_init(struct pci_dev *dev,
 
 	for (i = 0; i < nvec; i++) {
 		entry = alloc_msi_entry(dev);
-		if (!entry)
-			break;
+		if (!entry) {
+			msi_free_irqs(dev);
+			return -ENOMEM;
+		}
 
 		j = entries[i].entry;
 		entry->msi_attrib.is_msix = 1;

One concern is if we don't have enough memory to have number of entries
requested at first time, the driver will get -ENOMEM and will not do retry
even if we can have less number of entries.

i.e. if the driver can handle its device with 32 or 16 or 8 vectors, and
if there are only memory for 24 entries, and if there are only 30 vectors
available, the best return value of pci_enable_msix() will be 24.
It will let the driver to do retry with 16.

In current code, the return value of pci_enable_msix() in the above case
might be 0 even it allocates 24 vectors while requested is 32.
Yes, it is broken.

The above patch hunk will fix the broken behavior, but it cannot handle
low-memory condition very well.  However we could have another patch for
that as improve later.


Thanks,
H.Seto

--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [DMA Engine]     [Linux Coverity]     [Linux USB]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Greybus]

  Powered by Linux