Commit 2e41f91d9e90e34254746fefcb7bb678a3c9d541

Authored by Jaidev Patwardhan
Committed by Ralf Baechle
1 parent 05cf20790b

MIPS: SMTC: Avoid queing multiple reschedule IPIs

Signed-off-by: Chris Dearman <chris@mips.com>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>

Showing 2 changed files with 31 additions and 4 deletions Side-by-side Diff

arch/mips/include/asm/smtc_ipi.h
... ... @@ -45,6 +45,7 @@
45 45 spinlock_t lock;
46 46 struct smtc_ipi *tail;
47 47 int depth;
  48 + int resched_flag; /* reschedule already queued */
48 49 };
49 50  
50 51 static inline void smtc_ipi_nq(struct smtc_ipi_q *q, struct smtc_ipi *p)
arch/mips/kernel/smtc.c
... ... @@ -75,7 +75,6 @@
75 75  
76 76 asiduse smtc_live_asid[MAX_SMTC_TLBS][MAX_SMTC_ASIDS];
77 77  
78   -
79 78 /*
80 79 * Number of InterProcessor Interrupt (IPI) message buffers to allocate
81 80 */
... ... @@ -388,6 +387,7 @@
388 387 IPIQ[i].head = IPIQ[i].tail = NULL;
389 388 spin_lock_init(&IPIQ[i].lock);
390 389 IPIQ[i].depth = 0;
  390 + IPIQ[i].resched_flag = 0; /* No reschedules queued initially */
391 391 }
392 392  
393 393 /* cpu_data index starts at zero */
394 394  
395 395  
... ... @@ -741,11 +741,24 @@
741 741 static void smtc_ipi_qdump(void)
742 742 {
743 743 int i;
  744 + struct smtc_ipi *temp;
744 745  
745 746 for (i = 0; i < NR_CPUS ;i++) {
746   - printk("IPIQ[%d]: head = 0x%x, tail = 0x%x, depth = %d\n",
  747 + pr_info("IPIQ[%d]: head = 0x%x, tail = 0x%x, depth = %d\n",
747 748 i, (unsigned)IPIQ[i].head, (unsigned)IPIQ[i].tail,
748 749 IPIQ[i].depth);
  750 + temp = IPIQ[i].head;
  751 +
  752 + while (temp != IPIQ[i].tail) {
  753 + pr_debug("%d %d %d: ", temp->type, temp->dest,
  754 + (int)temp->arg);
  755 +#ifdef SMTC_IPI_DEBUG
  756 + pr_debug("%u %lu\n", temp->sender, temp->stamp);
  757 +#else
  758 + pr_debug("\n");
  759 +#endif
  760 + temp = temp->flink;
  761 + }
749 762 }
750 763 }
751 764  
752 765  
... ... @@ -784,11 +797,16 @@
784 797 int mtflags;
785 798 unsigned long tcrestart;
786 799 extern void r4k_wait_irqoff(void), __pastwait(void);
  800 + int set_resched_flag = (type == LINUX_SMP_IPI &&
  801 + action == SMP_RESCHEDULE_YOURSELF);
787 802  
788 803 if (cpu == smp_processor_id()) {
789 804 printk("Cannot Send IPI to self!\n");
790 805 return;
791 806 }
  807 + if (set_resched_flag && IPIQ[cpu].resched_flag != 0)
  808 + return; /* There is a reschedule queued already */
  809 +
792 810 /* Set up a descriptor, to be delivered either promptly or queued */
793 811 pipi = smtc_ipi_dq(&freeIPIq);
794 812 if (pipi == NULL) {
... ... @@ -801,6 +819,7 @@
801 819 pipi->dest = cpu;
802 820 if (cpu_data[cpu].vpe_id != cpu_data[smp_processor_id()].vpe_id) {
803 821 /* If not on same VPE, enqueue and send cross-VPE interrupt */
  822 + IPIQ[cpu].resched_flag |= set_resched_flag;
804 823 smtc_ipi_nq(&IPIQ[cpu], pipi);
805 824 LOCK_CORE_PRA();
806 825 settc(cpu_data[cpu].tc_id);
... ... @@ -847,6 +866,7 @@
847 866 */
848 867 write_tc_c0_tchalt(0);
849 868 UNLOCK_CORE_PRA();
  869 + IPIQ[cpu].resched_flag |= set_resched_flag;
850 870 smtc_ipi_nq(&IPIQ[cpu], pipi);
851 871 } else {
852 872 postdirect:
853 873  
854 874  
... ... @@ -996,12 +1016,15 @@
996 1016 * already enabled.
997 1017 */
998 1018 local_irq_save(flags);
999   -
1000 1019 spin_lock(&q->lock);
1001 1020 pipi = __smtc_ipi_dq(q);
1002 1021 spin_unlock(&q->lock);
1003   - if (pipi != NULL)
  1022 + if (pipi != NULL) {
  1023 + if (pipi->type == LINUX_SMP_IPI &&
  1024 + (int)pipi->arg == SMP_RESCHEDULE_YOURSELF)
  1025 + IPIQ[cpu].resched_flag = 0;
1004 1026 ipi_decode(pipi);
  1027 + }
1005 1028 /*
1006 1029 * The use of the __raw_local restore isn't
1007 1030 * as obviously necessary here as in smtc_ipi_replay(),
... ... @@ -1082,6 +1105,9 @@
1082 1105 * with interrupts off
1083 1106 */
1084 1107 local_irq_save(flags);
  1108 + if (pipi->type == LINUX_SMP_IPI &&
  1109 + (int)pipi->arg == SMP_RESCHEDULE_YOURSELF)
  1110 + IPIQ[cpu].resched_flag = 0;
1085 1111 ipi_decode(pipi);
1086 1112 local_irq_restore(flags);
1087 1113 }