Skip to content

Commit

Permalink
MIPS: SMTC: Avoid queing multiple reschedule IPIs
Browse files Browse the repository at this point in the history
Signed-off-by: Chris Dearman <chris@mips.com>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
  • Loading branch information
Jaidev Patwardhan authored and Ralf Baechle committed Nov 2, 2009
1 parent 05cf207 commit 2e41f91
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 4 deletions.
1 change: 1 addition & 0 deletions arch/mips/include/asm/smtc_ipi.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ struct smtc_ipi_q {
spinlock_t lock;
struct smtc_ipi *tail;
int depth;
int resched_flag; /* reschedule already queued */
};

static inline void smtc_ipi_nq(struct smtc_ipi_q *q, struct smtc_ipi *p)
Expand Down
34 changes: 30 additions & 4 deletions arch/mips/kernel/smtc.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@ unsigned long irq_hwmask[NR_IRQS];

asiduse smtc_live_asid[MAX_SMTC_TLBS][MAX_SMTC_ASIDS];


/*
* Number of InterProcessor Interrupt (IPI) message buffers to allocate
*/
Expand Down Expand Up @@ -388,6 +387,7 @@ void smtc_prepare_cpus(int cpus)
IPIQ[i].head = IPIQ[i].tail = NULL;
spin_lock_init(&IPIQ[i].lock);
IPIQ[i].depth = 0;
IPIQ[i].resched_flag = 0; /* No reschedules queued initially */
}

/* cpu_data index starts at zero */
Expand Down Expand Up @@ -741,11 +741,24 @@ void smtc_forward_irq(unsigned int irq)
static void smtc_ipi_qdump(void)
{
int i;
struct smtc_ipi *temp;

for (i = 0; i < NR_CPUS ;i++) {
printk("IPIQ[%d]: head = 0x%x, tail = 0x%x, depth = %d\n",
pr_info("IPIQ[%d]: head = 0x%x, tail = 0x%x, depth = %d\n",
i, (unsigned)IPIQ[i].head, (unsigned)IPIQ[i].tail,
IPIQ[i].depth);
temp = IPIQ[i].head;

while (temp != IPIQ[i].tail) {
pr_debug("%d %d %d: ", temp->type, temp->dest,
(int)temp->arg);
#ifdef SMTC_IPI_DEBUG
pr_debug("%u %lu\n", temp->sender, temp->stamp);
#else
pr_debug("\n");
#endif
temp = temp->flink;
}
}
}

Expand Down Expand Up @@ -784,11 +797,16 @@ void smtc_send_ipi(int cpu, int type, unsigned int action)
int mtflags;
unsigned long tcrestart;
extern void r4k_wait_irqoff(void), __pastwait(void);
int set_resched_flag = (type == LINUX_SMP_IPI &&
action == SMP_RESCHEDULE_YOURSELF);

if (cpu == smp_processor_id()) {
printk("Cannot Send IPI to self!\n");
return;
}
if (set_resched_flag && IPIQ[cpu].resched_flag != 0)
return; /* There is a reschedule queued already */

/* Set up a descriptor, to be delivered either promptly or queued */
pipi = smtc_ipi_dq(&freeIPIq);
if (pipi == NULL) {
Expand All @@ -801,6 +819,7 @@ void smtc_send_ipi(int cpu, int type, unsigned int action)
pipi->dest = cpu;
if (cpu_data[cpu].vpe_id != cpu_data[smp_processor_id()].vpe_id) {
/* If not on same VPE, enqueue and send cross-VPE interrupt */
IPIQ[cpu].resched_flag |= set_resched_flag;
smtc_ipi_nq(&IPIQ[cpu], pipi);
LOCK_CORE_PRA();
settc(cpu_data[cpu].tc_id);
Expand Down Expand Up @@ -847,6 +866,7 @@ void smtc_send_ipi(int cpu, int type, unsigned int action)
*/
write_tc_c0_tchalt(0);
UNLOCK_CORE_PRA();
IPIQ[cpu].resched_flag |= set_resched_flag;
smtc_ipi_nq(&IPIQ[cpu], pipi);
} else {
postdirect:
Expand Down Expand Up @@ -996,12 +1016,15 @@ void deferred_smtc_ipi(void)
* already enabled.
*/
local_irq_save(flags);

spin_lock(&q->lock);
pipi = __smtc_ipi_dq(q);
spin_unlock(&q->lock);
if (pipi != NULL)
if (pipi != NULL) {
if (pipi->type == LINUX_SMP_IPI &&
(int)pipi->arg == SMP_RESCHEDULE_YOURSELF)
IPIQ[cpu].resched_flag = 0;
ipi_decode(pipi);
}
/*
* The use of the __raw_local restore isn't
* as obviously necessary here as in smtc_ipi_replay(),
Expand Down Expand Up @@ -1082,6 +1105,9 @@ static irqreturn_t ipi_interrupt(int irq, void *dev_idm)
* with interrupts off
*/
local_irq_save(flags);
if (pipi->type == LINUX_SMP_IPI &&
(int)pipi->arg == SMP_RESCHEDULE_YOURSELF)
IPIQ[cpu].resched_flag = 0;
ipi_decode(pipi);
local_irq_restore(flags);
}
Expand Down

0 comments on commit 2e41f91

Please sign in to comment.