Commit ded86d8d37736df67ddeec4ae00e2ec1a5a90b3c

Authored by Eric W. Biederman
Committed by Greg Kroah-Hartman
1 parent 8fed4b6523

msi: Kill msi_lookup_irq

The function msi_lookup_irq was horrible.  As a side effect of running
it changed dev->irq, and then the callers would need to change it
back.  In addition it does a global scan through all of the irqs,
which seems to be the sole justification of the msi_lock.

To remove the neede for msi_lookup_irq I added first_msi_irq to struct
pci_dev.  Then depending on the context I replaced msi_lookup_irq with
dev->first_msi_irq, dev->msi_enabled, or dev->msix_enabled.

msi_enabled and msix_enabled were already present in pci_dev for other
reasons.

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
Acked-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

Showing 2 changed files with 62 additions and 90 deletions Side-by-side Diff

... ... @@ -272,28 +272,6 @@
272 272 pci_intx(dev, 1); /* enable intx */
273 273 }
274 274  
275   -static int msi_lookup_irq(struct pci_dev *dev, int type)
276   -{
277   - int irq;
278   - unsigned long flags;
279   -
280   - spin_lock_irqsave(&msi_lock, flags);
281   - for (irq = 0; irq < NR_IRQS; irq++) {
282   - if (!msi_desc[irq] || msi_desc[irq]->dev != dev ||
283   - msi_desc[irq]->msi_attrib.type != type ||
284   - msi_desc[irq]->msi_attrib.default_irq != dev->irq)
285   - continue;
286   - spin_unlock_irqrestore(&msi_lock, flags);
287   - /* This pre-assigned MSI irq for this device
288   - already exists. Override dev->irq with this irq */
289   - dev->irq = irq;
290   - return 0;
291   - }
292   - spin_unlock_irqrestore(&msi_lock, flags);
293   -
294   - return -EACCES;
295   -}
296   -
297 275 #ifdef CONFIG_PM
298 276 static int __pci_save_msi_state(struct pci_dev *dev)
299 277 {
300 278  
... ... @@ -364,11 +342,13 @@
364 342 static int __pci_save_msix_state(struct pci_dev *dev)
365 343 {
366 344 int pos;
367   - int temp;
368 345 int irq, head, tail = 0;
369 346 u16 control;
370 347 struct pci_cap_saved_state *save_state;
371 348  
  349 + if (!dev->msix_enabled)
  350 + return 0;
  351 +
372 352 pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
373 353 if (pos <= 0 || dev->no_msi)
374 354 return 0;
... ... @@ -386,13 +366,7 @@
386 366 *((u16 *)&save_state->data[0]) = control;
387 367  
388 368 /* save the table */
389   - temp = dev->irq;
390   - if (msi_lookup_irq(dev, PCI_CAP_ID_MSIX)) {
391   - kfree(save_state);
392   - return -EINVAL;
393   - }
394   -
395   - irq = head = dev->irq;
  369 + irq = head = dev->first_msi_irq;
396 370 while (head != tail) {
397 371 struct msi_desc *entry;
398 372  
... ... @@ -402,7 +376,6 @@
402 376 tail = msi_desc[irq]->link.tail;
403 377 irq = tail;
404 378 }
405   - dev->irq = temp;
406 379  
407 380 save_state->cap_nr = PCI_CAP_ID_MSIX;
408 381 pci_add_saved_cap(dev, save_state);
409 382  
... ... @@ -428,9 +401,11 @@
428 401 int pos;
429 402 int irq, head, tail = 0;
430 403 struct msi_desc *entry;
431   - int temp;
432 404 struct pci_cap_saved_state *save_state;
433 405  
  406 + if (!dev->msix_enabled)
  407 + return;
  408 +
434 409 save_state = pci_find_saved_cap(dev, PCI_CAP_ID_MSIX);
435 410 if (!save_state)
436 411 return;
... ... @@ -443,10 +418,7 @@
443 418 return;
444 419  
445 420 /* route the table */
446   - temp = dev->irq;
447   - if (msi_lookup_irq(dev, PCI_CAP_ID_MSIX))
448   - return;
449   - irq = head = dev->irq;
  421 + irq = head = dev->first_msi_irq;
450 422 while (head != tail) {
451 423 entry = msi_desc[irq];
452 424 write_msi_msg(irq, &entry->msg_save);
... ... @@ -454,7 +426,6 @@
454 426 tail = msi_desc[irq]->link.tail;
455 427 irq = tail;
456 428 }
457   - dev->irq = temp;
458 429  
459 430 pci_write_config_word(dev, msi_control_reg(pos), save);
460 431 enable_msi_mode(dev, pos, PCI_CAP_ID_MSIX);
... ... @@ -524,6 +495,7 @@
524 495 return status;
525 496 }
526 497  
  498 + dev->first_msi_irq = irq;
527 499 attach_msi_entry(entry, irq);
528 500 /* Set MSI enabled bits */
529 501 enable_msi_mode(dev, pos, PCI_CAP_ID_MSI);
... ... @@ -620,6 +592,7 @@
620 592 avail = -EBUSY;
621 593 return avail;
622 594 }
  595 + dev->first_msi_irq = entries[0].vector;
623 596 /* Set MSI-X enabled bits */
624 597 enable_msi_mode(dev, pos, PCI_CAP_ID_MSIX);
625 598  
626 599  
... ... @@ -667,13 +640,11 @@
667 640 **/
668 641 int pci_enable_msi(struct pci_dev* dev)
669 642 {
670   - int pos, temp, status;
  643 + int pos, status;
671 644  
672 645 if (pci_msi_supported(dev) < 0)
673 646 return -EINVAL;
674 647  
675   - temp = dev->irq;
676   -
677 648 status = msi_init();
678 649 if (status < 0)
679 650 return status;
680 651  
681 652  
682 653  
... ... @@ -682,15 +653,14 @@
682 653 if (!pos)
683 654 return -EINVAL;
684 655  
685   - WARN_ON(!msi_lookup_irq(dev, PCI_CAP_ID_MSI));
  656 + WARN_ON(!!dev->msi_enabled);
686 657  
687 658 /* Check whether driver already requested for MSI-X irqs */
688 659 pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
689   - if (pos > 0 && !msi_lookup_irq(dev, PCI_CAP_ID_MSIX)) {
  660 + if (pos > 0 && dev->msix_enabled) {
690 661 printk(KERN_INFO "PCI: %s: Can't enable MSI. "
691   - "Device already has MSI-X irq assigned\n",
  662 + "Device already has MSI-X enabled\n",
692 663 pci_name(dev));
693   - dev->irq = temp;
694 664 return -EINVAL;
695 665 }
696 666 status = msi_capability_init(dev);
... ... @@ -709,6 +679,9 @@
709 679 if (!dev)
710 680 return;
711 681  
  682 + if (!dev->msi_enabled)
  683 + return;
  684 +
712 685 pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
713 686 if (!pos)
714 687 return;
715 688  
716 689  
717 690  
718 691  
719 692  
... ... @@ -717,28 +690,30 @@
717 690 if (!(control & PCI_MSI_FLAGS_ENABLE))
718 691 return;
719 692  
  693 +
720 694 disable_msi_mode(dev, pos, PCI_CAP_ID_MSI);
721 695  
722 696 spin_lock_irqsave(&msi_lock, flags);
723   - entry = msi_desc[dev->irq];
  697 + entry = msi_desc[dev->first_msi_irq];
724 698 if (!entry || !entry->dev || entry->msi_attrib.type != PCI_CAP_ID_MSI) {
725 699 spin_unlock_irqrestore(&msi_lock, flags);
726 700 return;
727 701 }
728   - if (irq_has_action(dev->irq)) {
  702 + if (irq_has_action(dev->first_msi_irq)) {
729 703 spin_unlock_irqrestore(&msi_lock, flags);
730 704 printk(KERN_WARNING "PCI: %s: pci_disable_msi() called without "
731 705 "free_irq() on MSI irq %d\n",
732   - pci_name(dev), dev->irq);
733   - BUG_ON(irq_has_action(dev->irq));
  706 + pci_name(dev), dev->first_msi_irq);
  707 + BUG_ON(irq_has_action(dev->first_msi_irq));
734 708 } else {
735 709 default_irq = entry->msi_attrib.default_irq;
736 710 spin_unlock_irqrestore(&msi_lock, flags);
737   - msi_free_irq(dev, dev->irq);
  711 + msi_free_irq(dev, dev->first_msi_irq);
738 712  
739 713 /* Restore dev->irq to its default pin-assertion irq */
740 714 dev->irq = default_irq;
741 715 }
  716 + dev->first_msi_irq = 0;
742 717 }
743 718  
744 719 static int msi_free_irq(struct pci_dev* dev, int irq)
... ... @@ -797,7 +772,7 @@
797 772 int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec)
798 773 {
799 774 int status, pos, nr_entries;
800   - int i, j, temp;
  775 + int i, j;
801 776 u16 control;
802 777  
803 778 if (!entries || pci_msi_supported(dev) < 0)
804 779  
805 780  
... ... @@ -825,16 +800,14 @@
825 800 return -EINVAL; /* duplicate entry */
826 801 }
827 802 }
828   - temp = dev->irq;
829   - WARN_ON(!msi_lookup_irq(dev, PCI_CAP_ID_MSIX));
  803 + WARN_ON(!!dev->msix_enabled);
830 804  
831 805 /* Check whether driver already requested for MSI irq */
832 806 if (pci_find_capability(dev, PCI_CAP_ID_MSI) > 0 &&
833   - !msi_lookup_irq(dev, PCI_CAP_ID_MSI)) {
  807 + dev->msi_enabled) {
834 808 printk(KERN_INFO "PCI: %s: Can't enable MSI-X. "
835 809 "Device already has an MSI irq assigned\n",
836 810 pci_name(dev));
837   - dev->irq = temp;
838 811 return -EINVAL;
839 812 }
840 813 status = msix_capability_init(dev, entries, nvec);
... ... @@ -843,7 +816,9 @@
843 816  
844 817 void pci_disable_msix(struct pci_dev* dev)
845 818 {
846   - int pos, temp;
  819 + int irq, head, tail = 0, warning = 0;
  820 + unsigned long flags;
  821 + int pos;
847 822 u16 control;
848 823  
849 824 if (!pci_msi_enable)
... ... @@ -851,6 +826,9 @@
851 826 if (!dev)
852 827 return;
853 828  
  829 + if (!dev->msix_enabled)
  830 + return;
  831 +
854 832 pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
855 833 if (!pos)
856 834 return;
857 835  
... ... @@ -861,31 +839,25 @@
861 839  
862 840 disable_msi_mode(dev, pos, PCI_CAP_ID_MSIX);
863 841  
864   - temp = dev->irq;
865   - if (!msi_lookup_irq(dev, PCI_CAP_ID_MSIX)) {
866   - int irq, head, tail = 0, warning = 0;
867   - unsigned long flags;
868   -
869   - irq = head = dev->irq;
870   - dev->irq = temp; /* Restore pin IRQ */
871   - while (head != tail) {
872   - spin_lock_irqsave(&msi_lock, flags);
873   - tail = msi_desc[irq]->link.tail;
874   - spin_unlock_irqrestore(&msi_lock, flags);
875   - if (irq_has_action(irq))
876   - warning = 1;
877   - else if (irq != head) /* Release MSI-X irq */
878   - msi_free_irq(dev, irq);
879   - irq = tail;
880   - }
881   - msi_free_irq(dev, irq);
882   - if (warning) {
883   - printk(KERN_WARNING "PCI: %s: pci_disable_msix() called without "
884   - "free_irq() on all MSI-X irqs\n",
885   - pci_name(dev));
886   - BUG_ON(warning > 0);
887   - }
  842 + irq = head = dev->first_msi_irq;
  843 + while (head != tail) {
  844 + spin_lock_irqsave(&msi_lock, flags);
  845 + tail = msi_desc[irq]->link.tail;
  846 + spin_unlock_irqrestore(&msi_lock, flags);
  847 + if (irq_has_action(irq))
  848 + warning = 1;
  849 + else if (irq != head) /* Release MSI-X irq */
  850 + msi_free_irq(dev, irq);
  851 + irq = tail;
888 852 }
  853 + msi_free_irq(dev, irq);
  854 + if (warning) {
  855 + printk(KERN_WARNING "PCI: %s: pci_disable_msix() called without "
  856 + "free_irq() on all MSI-X irqs\n",
  857 + pci_name(dev));
  858 + BUG_ON(warning > 0);
  859 + }
  860 + dev->first_msi_irq = 0;
889 861 }
890 862  
891 863 /**
892 864  
893 865  
894 866  
895 867  
896 868  
897 869  
... ... @@ -899,30 +871,28 @@
899 871 **/
900 872 void msi_remove_pci_irq_vectors(struct pci_dev* dev)
901 873 {
902   - int pos, temp;
  874 + int pos;
903 875 unsigned long flags;
904 876  
905 877 if (!pci_msi_enable || !dev)
906 878 return;
907 879  
908   - temp = dev->irq; /* Save IOAPIC IRQ */
909 880 pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
910   - if (pos > 0 && !msi_lookup_irq(dev, PCI_CAP_ID_MSI)) {
911   - if (irq_has_action(dev->irq)) {
  881 + if (pos > 0 && dev->msi_enabled) {
  882 + if (irq_has_action(dev->first_msi_irq)) {
912 883 printk(KERN_WARNING "PCI: %s: msi_remove_pci_irq_vectors() "
913 884 "called without free_irq() on MSI irq %d\n",
914   - pci_name(dev), dev->irq);
915   - BUG_ON(irq_has_action(dev->irq));
  885 + pci_name(dev), dev->first_msi_irq);
  886 + BUG_ON(irq_has_action(dev->first_msi_irq));
916 887 } else /* Release MSI irq assigned to this device */
917   - msi_free_irq(dev, dev->irq);
918   - dev->irq = temp; /* Restore IOAPIC IRQ */
  888 + msi_free_irq(dev, dev->first_msi_irq);
919 889 }
920 890 pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
921   - if (pos > 0 && !msi_lookup_irq(dev, PCI_CAP_ID_MSIX)) {
  891 + if (pos > 0 && dev->msix_enabled) {
922 892 int irq, head, tail = 0, warning = 0;
923 893 void __iomem *base = NULL;
924 894  
925   - irq = head = dev->irq;
  895 + irq = head = dev->first_msi_irq;
926 896 while (head != tail) {
927 897 spin_lock_irqsave(&msi_lock, flags);
928 898 tail = msi_desc[irq]->link.tail;
... ... @@ -942,7 +912,6 @@
942 912 pci_name(dev));
943 913 BUG_ON(warning > 0);
944 914 }
945   - dev->irq = temp; /* Restore IOAPIC IRQ */
946 915 }
947 916 }
948 917  
... ... @@ -174,6 +174,9 @@
174 174 struct bin_attribute *rom_attr; /* attribute descriptor for sysfs ROM entry */
175 175 int rom_attr_enabled; /* has display of the rom attribute been enabled? */
176 176 struct bin_attribute *res_attr[DEVICE_COUNT_RESOURCE]; /* sysfs file for resources */
  177 +#ifdef CONFIG_PCI_MSI
  178 + unsigned int first_msi_irq;
  179 +#endif
177 180 };
178 181  
179 182 #define pci_dev_g(n) list_entry(n, struct pci_dev, global_list)