static int
restart_trace(struct notifier_block *nfb, unsigned long action, void *hcpu)
{
	unsigned int cpu;
	volatile int *pwr_down;

	cpu = (unsigned int)hcpu;

	switch (action) {
	case CPU_STARTING:
		switch (cpu) {
		case 1:
		case 2:
		case 3:
			pwr_down = &get_cpu_var(trace_pwr_down);
			if (*pwr_down) {
				trace_start_by_cpus(cpumask_of(cpu), 0);
				*pwr_down = 0;
			}
			put_cpu_var(trace_pwr_down);
			break;

		default:
			break;
		}

		break;

	case CPU_DYING:
		switch (cpu) {
#if 0
		case 2:
		case 3:
			if (!cpu_online(cpu ^ 1)) {
				per_cpu(trace_pwr_down, 2) = 1;
				per_cpu(trace_pwr_down, 3) = 1;
			}
			break;
#endif
		default:
			break;
		}

		break;

	default:
		break;
	}

	return NOTIFY_OK;
}
void trace_start_dormant(void)
{
	int cpu;

	trace_start_by_cpus(cpumask_of(0), 1);

	/*
	 * XXX: This function is called just before entering the suspend mode.
	 *	  The Linux kernel is already freeze.
	 *	  So it is safe to do the trick to access the per-cpu variable directly.
	 */
	for (cpu = 1; cpu < NR_CPUS; cpu++) {
		per_cpu(trace_pwr_down, cpu) = 1;
	}
}
static int
restart_trace(struct notifier_block *nfb, unsigned long action, void *hcpu)
{
	unsigned int cpu;
	volatile int *pwr_down;

	cpu = (unsigned int)hcpu;
	unsigned int cpu_ix = 0;

	switch (action) {
	case CPU_STARTING:
		switch (cpu) {
		case 1:
		case 2:
		case 3:
		case 4:
		case 5:
		case 6:
		case 7:
			pwr_down = &get_cpu_var(trace_pwr_down);
			if (*pwr_down) {
				trace_start_by_cpus(cpumask_of(cpu), 0);
				*pwr_down = 0;
			}
			put_cpu_var(trace_pwr_down);
			break;

		default:
			break;
		}

		break;

	case CPU_DYING:
		switch (cpu) {
		case 4:
		case 5:
		case 6:
		case 7:
                    if (num_possible_cpus() > 4) 
                    {
                        if ((!cpu_online(4)) && (!cpu_online(5)) && (!cpu_online(6)) && (!cpu_online(7))) {
			    // num_possible_cpus could be 4, 6, 8
			    for (cpu_ix = 4; cpu_ix < num_possible_cpus(); cpu_ix++) {
				per_cpu(trace_pwr_down, cpu_ix) = 1;
			    }
                        }
                    }
			break;

		default:
			break;
		}

		break;

	default:
		break;
	}

	return NOTIFY_OK;
}