Skip to content

Commit

Permalink
Trivial scheduler fix (isolcpus bug)
Browse files Browse the repository at this point in the history
Signed-off-by: Alec Ari <neotheuser@ymail.com>
  • Loading branch information
NTULINUX committed Aug 24, 2014
1 parent 3086517 commit e53f838
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 103 deletions.
76 changes: 1 addition & 75 deletions base/arch/x86/hal/hal.c
Expand Up @@ -159,12 +159,7 @@ static void sync_tsc(unsigned long master, unsigned int slave)
long long delta, rt = 0, master_time_stamp = 0;

go[MASTER] = 1;
if (smp_call_function(sync_master, (void *)master,
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
1,
#endif
0) < 0) {
// printk(KERN_ERR "sync_tsc: slave CPU %u failed to get attention from master CPU %u!\n", slave, master);
if (smp_call_function(sync_master, (void *)master, 0) < 0) {
return;
}
while (go[MASTER]) {
Expand Down Expand Up @@ -222,72 +217,3 @@ void cleanup_tsc_sync(void)
}

#endif /* defined(CONFIG_SMP) && defined(CONFIG_RTAI_DIAG_TSC_SYNC) */

#define CAL_LOOPS 200
int rtai_calibrate_hard_timer(void)
{
unsigned long flags;
RTIME t;
int i, dt;

flags = rtai_critical_enter(NULL);
#ifdef CONFIG_X86_LOCAL_APIC
t = rtai_rdtsc();
for (i = 0; i < CAL_LOOPS; i++) {
apic_write_around(APIC_TMICT, 8000);
}
#else
outb(0x34, 0x43);
t = rtai_rdtsc();
for (i = 0; i < CAL_LOOPS; i++) {
outb(LATCH & 0xff,0x40);
outb(LATCH >> 8,0x40);
}
#endif
dt = (int)(rtai_rdtsc() - t);
rtai_critical_exit(flags);
return rtai_imuldiv((dt + CAL_LOOPS/2)/CAL_LOOPS, 1000000000, rtai_tunables.cpu_freq);
}
EXPORT_SYMBOL(rtai_calibrate_hard_timer);

#ifdef CONFIG_SMP

extern int rtai_sched_affinity; // in Linux "kernel/sched/core.c"
// should we hold a lock for p->cpus_allowed, risky ?
void free_isolcpus_from_linux(void *IsolCpusMask)
{
struct task_struct *p;
struct cpumask mask;

rtai_sched_affinity = 1;
for_each_process(p) {
if (p->rtai_tskext(TSKEXT0)) {
continue;
}
cpumask_andnot(&mask, &p->cpus_allowed, (struct cpumask *)IsolCpusMask);
if (!cpumask_weight(&mask)) {
cpumask_complement(&mask, (struct cpumask *)IsolCpusMask);
}
#if 0 // diagnostic
{
char buf[4*sizeof(struct cpumask)];
cpumask_scnprintf(buf, sizeof(buf), &p->cpus_allowed);
printk("PID: %d, ORIG: %s ", p->pid, buf);
cpulist_scnprintf(buf, sizeof(buf), &p->cpus_allowed);
printk("(%s), ", buf);
cpumask_scnprintf(buf, sizeof(buf), &mask);
printk("NEW: %s ", buf);
cpulist_scnprintf(buf, sizeof(buf), &mask);
printk("(%s).\n", buf);
}
#endif
set_cpus_allowed_ptr(p, &mask);
}
}

#else

void free_isolcpus_from_linux(void *IsolCpusMask) { return; }

#endif

67 changes: 52 additions & 15 deletions base/arch/x86/hal/hal_64.c
Expand Up @@ -96,15 +96,15 @@ static void rtai_release_tickdev(void);
static inline void rtai_setup_periodic_apic (unsigned count, unsigned vector)
{
apic_read(APIC_LVTT);
apic_write(APIC_LVTT, APIC_LVT_TIMER_PERIODIC | vector);
apic_write(APIC_LVTT, APIC_INTEGRATED(GET_APIC_VERSION(apic_read(APIC_LVR))) ? SET_APIC_TIMER_BASE(APIC_TIMER_BASE_DIV) | APIC_LVT_TIMER_PERIODIC | vector : APIC_LVT_TIMER_PERIODIC | vector);
apic_read(APIC_TMICT);
apic_write(APIC_TMICT, count);
}

static inline void rtai_setup_oneshot_apic (unsigned count, unsigned vector)
{
apic_read(APIC_LVTT);
apic_write(APIC_LVTT, vector);
apic_write(APIC_LVTT, APIC_INTEGRATED(GET_APIC_VERSION(apic_read(APIC_LVR))) ? SET_APIC_TIMER_BASE(APIC_TIMER_BASE_DIV) | vector : vector);
apic_read(APIC_TMICT);
apic_write(APIC_TMICT, count);
}
Expand Down Expand Up @@ -222,8 +222,34 @@ int rt_release_irq (unsigned irq)
return 0;
}

#ifdef CONFIG_X86_IO_APIC
int ack_8259A_irq(unsigned int irq)
{
return 0;
}
#else
int ack_8259A_irq(unsigned int irq)
{
extern spinlock_t i8259A_lock;
spin_lock(&i8259A_lock);
if (irq & 8) {
outb(0x62,0x20);
outb(0x20,0xA0);
} else {
outb(0x20,0x20);
}
spin_unlock(&i8259A_lock);
return 0;
}
#endif

int rt_set_irq_ack(unsigned irq, int (*irq_ack)(unsigned int, void *))
{
#ifdef CONFIG_X86_IO_APIC
if (irq_ack == (void *)ack_8259A_irq) {
return -ENODEV;
}
#endif
if (irq >= RTAI_NR_IRQS) {
return -EINVAL;
}
Expand Down Expand Up @@ -561,6 +587,12 @@ void rt_end_irq (unsigned irq)

void rt_eoi_irq (unsigned irq)
{
if (
#ifdef CONFIG_X86_IO_APIC
!IO_APIC_IRQ(irq) ||
#endif /* CONFIG_X86_IO_APIC */
!(rtai_irq_desc(irq).status_use_accessors & (IRQD_IRQ_DISABLED | IRQD_IRQ_INPROGRESS))) {
}
rtai_irq_desc_chip(irq)->rtai_irq_endis_fun(eoi, irq);
}

Expand Down Expand Up @@ -924,8 +956,8 @@ void rt_request_apic_timers (void (*handler)(void), struct apic_timer_setup_data
}
}

rtai_critical_exit(flags);
rtai_request_tickdev(handler);
rtai_critical_exit(flags);
}

/**
Expand All @@ -942,8 +974,8 @@ void rt_free_apic_timers(void)
rtai_release_tickdev();
rtai_sync_level = 3;
rtai_setup_periodic_apic(RTAI_APIC_ICOUNT,LOCAL_TIMER_VECTOR);
rtai_critical_exit(flags);
rt_release_irq(RTAI_APIC_TIMER_IPI);
rtai_critical_exit(flags);
}

/**
Expand All @@ -966,8 +998,8 @@ void rt_free_apic_timers(void)
*/
unsigned long rt_assign_irq_to_cpu (int irq, unsigned long cpumask)
{
if (irq >= IPIPE_NR_XIRQS || &rtai_irq_desc(irq) == NULL || rtai_irq_desc_chip(irq) == NULL || rtai_irq_desc_chip(irq)->irq_set_affinity == NULL) {
return 0;
if (irq >= IPIPE_NR_XIRQS) {
return -EINVAL;
} else {
unsigned long oldmask, flags;

Expand Down Expand Up @@ -1251,14 +1283,7 @@ static int rtai_hirq_dispatcher (int irq)
return 0;
}

//#define HINT_DIAG_ECHO
//#define HINT_DIAG_TRAPS

#ifdef HINT_DIAG_ECHO
#define HINT_DIAG_MSG(x) x
#else
#define HINT_DIAG_MSG(x)
#endif

static int PrintFpuTrap = 0;
RTAI_MODULE_PARM(PrintFpuTrap, int);
Expand Down Expand Up @@ -1394,7 +1419,7 @@ static unsigned long hal_request_apic_freq(void);

static void rtai_install_archdep (void)
{
ipipe_select_timers(cpu_active_mask);
ipipe_select_timers(cpu_present_mask);
hal_catch_event(hal_root_domain, HAL_SYSCALL_PROLOGUE, (void *)intercept_syscall_prologue);

if (rtai_cpufreq_arg == 0) {
Expand Down Expand Up @@ -1595,6 +1620,7 @@ int __rtai_hal_init (void)
{
int trapnr, halinv = 0;
struct hal_attr_struct attr;
struct hal_sysinfo_struct sysinfo;

ipipe_catch_event(hal_root_domain, 0, 0);
for (halinv = trapnr = 0; trapnr < HAL_NR_EVENTS; trapnr++) {
Expand Down Expand Up @@ -1635,6 +1661,18 @@ int __rtai_hal_init (void)

rtai_install_archdep();

/* test if timers are available */
hal_get_sysinfo(&sysinfo);
if (!sysinfo.sys_hrtimer_freq || !sysinfo.sys_hrclock_freq || !sysinfo.sys_cpu_freq) {
printk(KERN_ERR "RTAI[hal]: NO CLOCK AVAILABLE.\n");
/* undo what is partially done, in order found in __rtai_hal_exit */
hal_irq_handler = NULL;
hal_virtualize_irq(hal_root_domain, rtai_sysreq_virq, NULL, NULL, 0);
hal_free_irq(rtai_sysreq_virq);
rtai_uninstall_archdep();
return -1;
}

#ifdef CONFIG_PROC_FS
rtai_proc_register();
#endif
Expand All @@ -1655,7 +1693,6 @@ int __rtai_hal_init (void)
for (trapnr = 0; trapnr < IPIPE_NR_XIRQS; trapnr++) {
rtai_orig_irq_affinity[trapnr] = rt_assign_irq_to_cpu(trapnr, ~IsolCpusMask);
}
free_isolcpus_from_linux(&IsolCpusMask);
}
#else
IsolCpusMask = 0;
Expand Down
19 changes: 6 additions & 13 deletions base/sched/sched.c
Expand Up @@ -2586,19 +2586,12 @@ static int __rtai_lxrt_init(void)
rt_linux_task.resq.task = NULL;
}
tuned.latency = imuldiv(Latency, tuned.cpu_freq, 1000000000);
tuned.kern_latency_busy_align_ret_delay = imuldiv(RTAI_KERN_BUSY_ALIGN_RET_DELAY, tuned.cpu_freq, 1000000000);
tuned.user_latency_busy_align_ret_delay = imuldiv(RTAI_USER_BUSY_ALIGN_RET_DELAY, tuned.cpu_freq, 1000000000);
SetupTimeTIMER = rtai_calibrate_hard_timer();
tuned.setup_time_TIMER_UNIT = imuldiv(SetupTimeTIMER, TIMER_FREQ, 1000000000);
if (tuned.setup_time_TIMER_UNIT < 1) {
tuned.setup_time_TIMER_UNIT = 1;
tuned.setup_time_TIMER_CPUNIT = (tuned.cpu_freq + TIMER_FREQ/2)/TIMER_FREQ;
} else {
tuned.setup_time_TIMER_CPUNIT = imuldiv(SetupTimeTIMER, tuned.cpu_freq, 1000000000);
}
if (tuned.latency < tuned.setup_time_TIMER_CPUNIT) {
tuned.latency = tuned.setup_time_TIMER_CPUNIT;
}
tuned.setup_time_TIMER_CPUNIT = imuldiv( SetupTimeTIMER,
tuned.cpu_freq,
1000000000);
tuned.setup_time_TIMER_UNIT = imuldiv( SetupTimeTIMER,
TIMER_FREQ,
1000000000);
tuned.timers_tol[0] = 0;
oneshot_span = ONESHOT_SPAN;
satdlay = oneshot_span - tuned.latency;
Expand Down

0 comments on commit e53f838

Please sign in to comment.