Re: [PATCH 3/3] PCI: add latency tolerance reporting enable/disable support

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

 



On Thu, 5 May 2011 13:51:58 -0600
Matthew Wilcox <matthew@xxxxxx> wrote:

> On Thu, May 05, 2011 at 12:33:50PM -0700, Jesse Barnes wrote:
> > +bool pci_ltr_supported(struct pci_dev *dev)
> > +{
> > +	int pos;
> > +	u32 cap;
> > +
> > +	if (!pci_is_pcie(dev))
> > +		return false;
> > +
> > +	pos = pci_pcie_cap(dev);
> > +	if (!pos)
> > +		return false;
> > +
> > +	pci_read_config_dword(dev, pos + PCI_EXP_DEVCAP2, &cap);
> > +
> > +	return cap & PCI_EXP_DEVCAP2_LTR;
> > +}
> 
> Missing EXPORT_SYMBOL?  (throughout)

Oops, will fix.  I guess drivers would have run into that pretty
quickly. :)

> 
> > +/**
> > + * pci_set_ltr - set LTR latency values
> > + * @dev: PCI device
> > + * @latencies: LTR latency values & scaling
> > + *
> > + * Set the LTR cap registers to the values provided by @latencies.
> > + */
> > +int pci_set_ltr(struct pci_dev *dev, struct pci_ltr_latencies *latencies)
> > +{
> 
> I don't like this API.  Why not just pass a u32 snoop_lat and nosnoop_lat
> (in ns) and do:
> 
> 	int scale = 0;
> 	while (latency > 1023) {
> 		latency = (latency + 31) / 32;
> 		scale++;
> 	}
> 
> (a u32 latency gives you up to 4 seconds of latency, which is surely
> more than any device can tolerate ... and doesn't let you max out scale)

Agreed, not sure why I thought this was a good API when I coded it up.
Taking simple ns is much easier from a caller perspective.

> > +	int pos, ret;
> > +	u32 val;
> > +
> > +	if (!pci_ltr_supported(dev))
> > +		return -ENOTSUPP;
> > +
> > +	if (latencies->max_snoop_value > PCI_LTR_VALUE_MASK ||
> > +	    latencies->max_nosnoop_value > PCI_LTR_VALUE_MASK)
> > +		return -EINVAL;
> > +
> > +	if ((latencies->max_snoop_scale >
> > +	     (PCI_LTR_SCALE_MASK >> PCI_LTR_SCALE_SHIFT)) ||
> > +	    (latencies->max_nosnoop_scale >
> > +	     (PCI_LTR_SCALE_MASK >> PCI_LTR_SCALE_SHIFT)))
> > +		return -EINVAL;
> > +
> > +	pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_LTR);
> > +	if (!pos)
> > +		return -ENOTSUPP;
> > +
> > +	val = (latencies->max_snoop_scale << PCI_LTR_SCALE_SHIFT) |
> > +		latencies->max_snoop_value;
> > +	ret = pci_write_config_dword(dev, pos + PCI_LTR_MAX_SNOOP_LAT, val);
> > +	if (ret != 4)
> > +		return -EIO;
> 
> Spec indicates these are word values ... can probably hit both registers
> with a single dword write though.

May as well split the writes up just to avoid confusion.

Thanks a lot for checking it out.

-- 
Jesse Barnes, Intel Open Source Technology Center
--
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