Пример #1
0
/*
 * This is used in working around bugs in thread reconfiguration
 * on POWER9 (at least up to Nimbus DD2.2) relating to transactional
 * memory and the way that XER[SO] is checkpointed.
 * This function forces the core into SMT4 in order by asking
 * all other threads not to stop, and sending a message to any
 * that are in a stop state.
 * Must be called with preemption disabled.
 */
void pnv_power9_force_smt4_catch(void)
{
	int cpu, cpu0, thr;
	int awake_threads = 1;		/* this thread is awake */
	int poke_threads = 0;
	int need_awake = threads_per_core;

	cpu = smp_processor_id();
	cpu0 = cpu & ~(threads_per_core - 1);
	for (thr = 0; thr < threads_per_core; ++thr) {
		if (cpu != cpu0 + thr)
			atomic_inc(&paca_ptrs[cpu0+thr]->dont_stop);
	}
	/* order setting dont_stop vs testing requested_psscr */
	mb();
	for (thr = 0; thr < threads_per_core; ++thr) {
		if (!paca_ptrs[cpu0+thr]->requested_psscr)
			++awake_threads;
		else
			poke_threads |= (1 << thr);
	}

	/* If at least 3 threads are awake, the core is in SMT4 already */
	if (awake_threads < need_awake) {
		/* We have to wake some threads; we'll use msgsnd */
		for (thr = 0; thr < threads_per_core; ++thr) {
			if (poke_threads & (1 << thr)) {
				ppc_msgsnd_sync();
				ppc_msgsnd(PPC_DBELL_MSGTYPE, 0,
					   paca_ptrs[cpu0+thr]->hw_cpu_id);
			}
		}
		/* now spin until at least 3 threads are awake */
		do {
			for (thr = 0; thr < threads_per_core; ++thr) {
				if ((poke_threads & (1 << thr)) &&
				    !paca_ptrs[cpu0+thr]->requested_psscr) {
					++awake_threads;
					poke_threads &= ~(1 << thr);
				}
			}
		} while (awake_threads < need_awake);
	}
}
void doorbell_cause_ipi(int cpu, unsigned long data)
{
	/* Order previous accesses vs. msgsnd, which is treated as a store */
	mb();
	ppc_msgsnd(PPC_DBELL, 0, data);
}
Пример #3
0
void doorbell_cause_ipi(int cpu, unsigned long data)
{
	ppc_msgsnd(PPC_DBELL, 0, data);
}