Skip to content

Commit

Permalink
intel_th: Disallow multi mode on devices where it's broken
Browse files Browse the repository at this point in the history
Some versions of Intel TH have an issue that prevents the multi mode of
MSU from working correctly, resulting in no trace data and potentially
stuck MSU pipeline.

Disable multi mode on such devices.

Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Link: https://lore.kernel.org/r/20200317062215.15598-2-alexander.shishkin@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Alexander Shishkin authored and Greg Kroah-Hartman committed Mar 18, 2020
1 parent 2cca608 commit 397c772
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 4 deletions.
2 changes: 2 additions & 0 deletions drivers/hwtracing/intel_th/intel_th.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,13 @@ struct intel_th_output {
/**
* struct intel_th_drvdata - describes hardware capabilities and quirks
* @tscu_enable: device needs SW to enable time stamping unit
* @multi_is_broken: device has multiblock mode is broken
* @has_mintctl: device has interrupt control (MINTCTL) register
* @host_mode_only: device can only operate in 'host debugger' mode
*/
struct intel_th_drvdata {
unsigned int tscu_enable : 1,
multi_is_broken : 1,
has_mintctl : 1,
host_mode_only : 1;
};
Expand Down
11 changes: 9 additions & 2 deletions drivers/hwtracing/intel_th/msu.c
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,8 @@ struct msc {
/* config */
unsigned int enabled : 1,
wrap : 1,
do_irq : 1;
do_irq : 1,
multi_is_broken : 1;
unsigned int mode;
unsigned int burst_len;
unsigned int index;
Expand Down Expand Up @@ -1664,7 +1665,7 @@ static int intel_th_msc_init(struct msc *msc)
{
atomic_set(&msc->user_count, -1);

msc->mode = MSC_MODE_MULTI;
msc->mode = msc->multi_is_broken ? MSC_MODE_SINGLE : MSC_MODE_MULTI;
mutex_init(&msc->buf_mutex);
INIT_LIST_HEAD(&msc->win_list);
INIT_LIST_HEAD(&msc->iter_list);
Expand Down Expand Up @@ -1876,6 +1877,9 @@ mode_store(struct device *dev, struct device_attribute *attr, const char *buf,
return -EINVAL;

found:
if (i == MSC_MODE_MULTI && msc->multi_is_broken)
return -EOPNOTSUPP;

mutex_lock(&msc->buf_mutex);
ret = 0;

Expand Down Expand Up @@ -2082,6 +2086,9 @@ static int intel_th_msc_probe(struct intel_th_device *thdev)
if (!res)
msc->do_irq = 1;

if (INTEL_TH_CAP(to_intel_th(thdev), multi_is_broken))
msc->multi_is_broken = 1;

msc->index = thdev->id;

msc->thdev = thdev;
Expand Down
8 changes: 6 additions & 2 deletions drivers/hwtracing/intel_th/pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,10 @@ static void intel_th_pci_remove(struct pci_dev *pdev)
pci_free_irq_vectors(pdev);
}

static const struct intel_th_drvdata intel_th_1x_multi_is_broken = {
.multi_is_broken = 1,
};

static const struct intel_th_drvdata intel_th_2x = {
.tscu_enable = 1,
.has_mintctl = 1,
Expand Down Expand Up @@ -152,7 +156,7 @@ static const struct pci_device_id intel_th_pci_id_table[] = {
{
/* Kaby Lake PCH-H */
PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa2a6),
.driver_data = (kernel_ulong_t)0,
.driver_data = (kernel_ulong_t)&intel_th_1x_multi_is_broken,
},
{
/* Denverton */
Expand Down Expand Up @@ -207,7 +211,7 @@ static const struct pci_device_id intel_th_pci_id_table[] = {
{
/* Comet Lake PCH-V */
PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa3a6),
.driver_data = (kernel_ulong_t)&intel_th_2x,
.driver_data = (kernel_ulong_t)&intel_th_1x_multi_is_broken,
},
{
/* Ice Lake NNPI */
Expand Down

0 comments on commit 397c772

Please sign in to comment.