~ubuntu-branches/debian/jessie/rtai/jessie

« back to all changes in this revision

Viewing changes to base/sched/sys.c

  • Committer: Bazaar Package Importer
  • Author(s): Roland Stigge
  • Date: 2009-07-04 11:47:08 UTC
  • mfrom: (1.2.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20090704114708-0ivbkccfaawz2pby
Tags: 3.7.1-1
* New upstream release
* debian/control: Standards-Version: 3.8.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * Copyright (C) 2001-2006  Paolo Mantegazza <mantegazza@aero.polimi.it>,
 
2
 * Copyright (C) 2001-2008  Paolo Mantegazza <mantegazza@aero.polimi.it>,
3
3
 *                          Pierre Cloutier <pcloutier@poseidoncontrols.com>,
4
4
 *                          Steve Papacharalambous <stevep@zentropix.com>.
5
5
 *
32
32
#include <linux/mman.h>
33
33
#include <asm/uaccess.h>
34
34
 
 
35
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18)
 
36
#include <linux/oom.h>
 
37
#endif
 
38
 
35
39
#include <rtai_sched.h>
36
40
#include <rtai_lxrt.h>
37
41
#include <rtai_sem.h>
246
250
#ifdef PF_EVNOTIFY
247
251
                        current->flags |= PF_EVNOTIFY;
248
252
#endif
249
 
#ifdef VM_PINNED
 
253
#if (defined VM_PINNED) && (defined CONFIG_MMU)
250
254
                        ipipe_disable_ondemand_mappings(current);
251
255
#endif
 
256
#ifdef OOM_DISABLE
 
257
                        current->oomkilladj = OOM_DISABLE;
 
258
#endif
252
259
 
253
260
                        return rt_task;
254
261
                } else {
265
272
static int __task_delete(RT_TASK *rt_task)
266
273
{
267
274
        struct task_struct *process;
 
275
 
 
276
        if (current != rt_task->lnxtsk) {
 
277
                return -EPERM;
 
278
        }
 
279
        if ((process = rt_task->lnxtsk)) {
 
280
                process->rtai_tskext(TSKEXT0) = process->rtai_tskext(TSKEXT1) = 0;
 
281
        }
 
282
        if (rt_task->is_hard > 0) {
 
283
                give_back_to_linux(rt_task, 0);
 
284
        }
268
285
        if (rt_task->linux_syscall_server) {
269
 
                rt_task_masked_unblock(rt_task->linux_syscall_server->task, ~RT_SCHED_READY);
270
 
        }
271
 
        if (current == rt_task->lnxtsk && rt_task->is_hard > 0) {
272
 
                give_back_to_linux(rt_task, 0);
 
286
                RT_TASK *serv = rt_task->linux_syscall_server->serv;
 
287
                serv->suspdepth = -RTE_HIGERR;
 
288
                rt_task_masked_unblock(serv, ~RT_SCHED_READY);
 
289
                process->state = TASK_INTERRUPTIBLE;
 
290
                schedule_timeout(HZ/10);
 
291
 
273
292
        }
274
293
        if (clr_rtext(rt_task)) {
275
294
                return -EFAULT;
277
296
        rt_free(rt_task->msg_buf[0]);
278
297
        rt_free(rt_task->msg_buf[1]);
279
298
        rt_free(rt_task);
280
 
        if ((process = rt_task->lnxtsk)) {
281
 
                process->rtai_tskext(TSKEXT0) = process->rtai_tskext(TSKEXT1) = 0;
282
 
        }
283
299
        return (!rt_drg_on_adr(rt_task)) ? -ENODEV : 0;
284
300
}
285
301
 
290
306
#define SYSW_DIAG_MSG(x)
291
307
#endif
292
308
 
293
 
#define recover_hardrt(chktsk, task) \
294
 
do { \
295
 
        if ((chktsk) && unlikely(((task)->is_hard) < 0)) { \
296
 
                SYSW_DIAG_MSG(rt_printk("GOING BACK TO HARD (SYSLXRT, DIRECT), PID = %d.\n", current->pid);); \
297
 
                steal_from_linux(task); \
298
 
                SYSW_DIAG_MSG(rt_printk("GONE BACK TO HARD (SYSLXRT),  PID = %d.\n", current->pid);); \
299
 
        } \
300
 
} while(0)
 
309
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,28)
 
310
 
 
311
#include <linux/cred.h>
 
312
static inline void set_lxrt_perm(int perm)
 
313
{
 
314
        struct cred *cred;
 
315
        if ((cred = prepare_creds())) {
 
316
                cap_raise(cred->cap_effective, perm);
 
317
                commit_creds(cred);
 
318
        }
 
319
}
 
320
 
 
321
#else /* LINUX_VERSION_CODE <= 2.6.28 */
 
322
 
 
323
static inline void set_lxrt_perm(int perm)
 
324
{
 
325
#ifdef current_cap
 
326
        cap_raise(current_cap(), perm);
 
327
#else
 
328
        cap_raise(current->cap_effective, perm);
 
329
#endif
 
330
}
 
331
 
 
332
#endif /* LINUX_VERSION_CODE > 2.6.28 */
 
333
 
 
334
void rt_make_hard_real_time(RT_TASK *task)
 
335
{
 
336
        if (task && task->magic == RT_TASK_MAGIC && !task->is_hard) {
 
337
                steal_from_linux(task);
 
338
        }
 
339
}
 
340
 
 
341
void rt_make_soft_real_time(RT_TASK *task)
 
342
{
 
343
        if (task && task->magic == RT_TASK_MAGIC && task->is_hard) {
 
344
                if (task->is_hard > 0) {
 
345
                        give_back_to_linux(task, 0);
 
346
                } else {
 
347
                        task->is_hard = 0;
 
348
                }
 
349
        }
 
350
}
301
351
 
302
352
static inline long long handle_lxrt_request (unsigned int lxsrq, long *arg, RT_TASK *task)
303
353
{
316
366
 * (giuseppe@renoldi.org).
317
367
 */
318
368
                if (unlikely(!(funcm = rt_fun_ext[INDX(lxsrq)]))) {
319
 
                        rt_printk("BAD: null rt_fun_ext[%d]\n", INDX(lxsrq));
 
369
                        rt_printk("BAD: null rt_fun_ext, no module for extension %d?\n", INDX(lxsrq));
320
370
                        return -ENOSYS;
321
371
                }
322
372
                if (!(type = funcm[srq].type)) {
323
 
                        recover_hardrt(task, task);
324
373
                        return ((RTAI_SYSCALL_MODE long long (*)(unsigned long, ...))funcm[srq].fun)(RTAI_FUN_ARGS);
325
374
                }
326
 
                recover_hardrt(1, task);
327
375
                if (unlikely(NEED_TO_RW(type))) {
328
376
                        lxrt_fun_call_wbuf(task, funcm[srq].fun, NARG(lxsrq), arg, type);
329
377
                } else {
463
511
                }
464
512
 
465
513
                case MAKE_HARD_RT: {
 
514
                        rt_make_hard_real_time(task);
 
515
                        return 0;
466
516
                        if (!task || task->is_hard) {
467
517
                                 return 0;
468
518
                        }
471
521
                }
472
522
 
473
523
                case MAKE_SOFT_RT: {
 
524
                        rt_make_soft_real_time(task);
 
525
                        return 0;
474
526
                        if (!task || !task->is_hard) {
475
527
                                return 0;
476
528
                        }
494
546
                }
495
547
 
496
548
                case NONROOT_HRT: {
 
549
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
497
550
                        current->cap_effective |= ((1 << CAP_IPC_LOCK)  |
498
 
                                                   (1 << CAP_SYS_RAWIO) | 
 
551
                                                   (1 << CAP_SYS_RAWIO) |
499
552
                                                   (1 << CAP_SYS_NICE));
 
553
#else
 
554
                        set_lxrt_perm(CAP_IPC_LOCK);
 
555
                        set_lxrt_perm(CAP_SYS_RAWIO);
 
556
                        set_lxrt_perm(CAP_SYS_NICE);
 
557
#endif
500
558
                        return 0;
501
559
                }
502
560
 
593
651
        return 0;
594
652
}
595
653
 
596
 
static inline void force_soft(RT_TASK *task)
 
654
static inline void check_to_soften_harden(RT_TASK *task)
597
655
{
598
656
        if (unlikely(task->force_soft)) {
599
 
                task->force_soft = 0;
600
 
                task->usp_flags &= ~FORCE_SOFT;
601
 
                give_back_to_linux(task, 0);
602
 
        }
603
 
}
604
 
 
605
 
#if 1  // restructured 
606
 
 
607
 
static inline void rt_do_signal(struct pt_regs *regs, RT_TASK *task)
608
 
{
609
 
        if (unlikely(task->unblocked)) {
610
657
                if (task->is_hard > 0) {
611
 
                        give_back_to_linux(task, task->force_soft ? 0 : -1);
 
658
                        give_back_to_linux(task, 0);
 
659
                } else {
 
660
                        task->is_hard = 0;
612
661
                }
613
 
#ifdef RTAI_DO_LINUX_SIGNAL
614
 
                do {
615
 
                        unsigned long saved_eax = regs->LINUX_SYSCALL_RETREG;
616
 
                        regs->LINUX_SYSCALL_RETREG = -ERESTARTSYS; // -EINTR;
617
 
                        RT_DO_SIGNAL(regs);
618
 
                        regs->LINUX_SYSCALL_RETREG = saved_eax;
619
 
                        if (task->is_hard < 0) {
620
 
                                steal_from_linux(task);
621
 
                        }
622
 
                } while (0);
623
 
#endif
624
662
                task->unblocked = task->force_soft = 0;
625
663
                task->usp_flags &= ~FORCE_SOFT;
626
 
                return;
627
 
        }
628
 
        force_soft(task);
629
 
}
630
 
 
631
 
long long rtai_lxrt_invoke (unsigned int lxsrq, void *arg, struct pt_regs *regs)
632
 
{
633
 
        RT_TASK *task;
634
 
 
635
 
        if (likely((task = current->rtai_tskext(TSKEXT0)) != NULL)) {
636
 
                long long retval;
637
 
                rt_do_signal(regs, task);
638
 
                retval = handle_lxrt_request(lxsrq, arg, task);
639
 
                rt_do_signal(regs, task);
640
 
                return retval;
641
 
        } else {
642
 
                return handle_lxrt_request(lxsrq, arg, task);
643
 
        }
644
 
}
645
 
 
646
 
#else  // end restructured, begin old
647
 
 
648
 
static inline int rt_do_signal(struct pt_regs *regs, RT_TASK *task)
649
 
{
650
 
        if (unlikely(task->unblocked)) {
651
 
                int retval = task->unblocked < 0;
 
664
        } else if (unlikely(task->is_hard < 0)) {
 
665
                SYSW_DIAG_MSG(rt_printk("GOING BACK TO HARD (SYSLXRT, DIRECT), PID = %d.\n", current->pid););
 
666
                steal_from_linux(task);
 
667
                SYSW_DIAG_MSG(rt_printk("GONE BACK TO HARD (SYSLXRT),  PID = %d.\n", current->pid););
 
668
        } else if (unlikely(task->unblocked)) {
652
669
                if (task->is_hard > 0) {
653
670
                        give_back_to_linux(task, -1);
654
671
                }
655
 
#ifdef RTAI_DO_LINUX_SIGNAL
656
 
                if (task->unblocked > 0) {
657
 
                        if (likely(regs->LINUX_SYSCALL_NR < RTAI_SYSCALL_NR)) {
658
 
                                unsigned long saved_eax = regs->LINUX_SYSCALL_RETREG;
659
 
                                regs->LINUX_SYSCALL_RETREG = -EINTR;
660
 
//                              regs->LINUX_SYSCALL_RETREG = -ERESTARTSYS;
661
 
                                RT_DO_SIGNAL(regs);
662
 
                                regs->LINUX_SYSCALL_RETREG = saved_eax;
663
 
                                if (task->is_hard < 0) {
664
 
                                        steal_from_linux(task);
665
 
                                }
666
 
                        }
667
 
                }
668
 
#endif
669
672
                task->unblocked = 0;
670
 
                return retval;
671
673
        }
672
 
        return 1;
673
674
}
674
675
 
675
 
long long rtai_lxrt_invoke (unsigned int lxsrq, void *arg, struct pt_regs *regs)
 
676
long long rtai_lxrt_invoke (unsigned int lxsrq, void *arg)
676
677
{
677
678
        RT_TASK *task;
678
679
 
679
680
        if (likely((task = current->rtai_tskext(TSKEXT0)) != NULL)) {
680
681
                long long retval;
681
 
                if (unlikely(rt_do_signal(regs, task))) {
682
 
                        force_soft(task);
683
 
                }
 
682
                check_to_soften_harden(task);
684
683
                retval = handle_lxrt_request(lxsrq, arg, task);
685
 
                if (unlikely(rt_do_signal(regs, task))) {
686
 
                        force_soft(task);
687
 
                }
 
684
                check_to_soften_harden(task);
688
685
                return retval;
689
 
        } else {
690
 
                return handle_lxrt_request(lxsrq, arg, task);
691
 
        }
 
686
        } 
 
687
 
 
688
        return handle_lxrt_request(lxsrq, arg, NULL);
692
689
}
693
690
 
694
 
#endif // end olf part of restructured
695
 
 
696
691
int set_rt_fun_ext_index(struct rt_fun_entry *fun, int idx)
697
692
{
698
693
        if (idx > 0 && idx < MAX_FUN_EXT && !rt_fun_ext[idx]) {
778
773
{
779
774
        rt_fun_ext[0] = rt_fun_lxrt;
780
775
}
 
776
 
 
777
EXPORT_SYMBOL(rt_make_hard_real_time);
 
778
EXPORT_SYMBOL(rt_make_soft_real_time);