UMS Scheduler

Overview

The life cycle of a UMS scheduler is bounded to the process that opens the UMS device and it is represented by the ums_scheduler structure. Once created, it is stored inside the pool of schedulers pointed by ums_data.schedulers. The kernel rhashtable structure has been choosen for representing the schedulers pool since the number of UMS schedulers that are going to be created isn’t known in advance. In this way the size of the hashtable will be automatically adjusted providing better performances. Every UMS scheduler is indexed inside the pool by its ums_scheduler.context.

UMS scheduling activities are notified to userland process by means of IOCTL_UMS_SCHED_DQEVENT ioctl calls. After a userland thread converts itself to UMS scheduling thread a ums_event_node of type ums_sched_event_type_e.SCHEDULER_STARTUP is posted to the newly created scheduler’s ums_scheduler.event_q; when an UMS worker thread yields or terminates a ums_event_node of type ums_sched_event_type_e.THREAD_YIELD or ums_sched_event_type_e.THREAD_TERMINATED is posted to the scheduler’s event queue.

Every ums_event_node is allocated by a dedicated slab cache in order to speed up allocation time. The dedicated slab cache is created when the UMS module is loaded by calling ums_scheduling_cache_create() and destroied when the module is unloaded by calling ums_scheduling_cache_destroy().

When a UMS scheduler is created it is registered to the dedicated UMS procfs at /proc/ums/<pid>/schedulers/<scheduler-pid>, where <pid> is the PID of the process that opens the UMS device and <scheduler-pid> is the PID of the UMS scheduler. Once a UMS scheduler terminates it is unregistered from the UMS procfs.

For every UMS worker that is dequeued by a UMS scheduler from its UMS completion list a symlink is created inside /proc/ums/<pid>/schedulers/<scheduler-pid>/workers folder and it is subsequently deleted when the UMS scheduler executes one of them. In this way at any time the /proc/ums/<pid>/schedulers/<scheduler-pid>/workers folder represents the list of UMS workers that an UMS scheduler is owning.

Defines

EVENT_ADD_HEAD

Add a UMS scheduling event to the head of the event queue

EVENT_ADD_TAIL

Add a UMS scheduling event to the tail of the event queue

Structs

struct ums_scheduler

UMS scheduler struct

Public Members

struct ums_context context

scheduler context

struct ums_complist *complist

scheduler completion list

struct list_head event_q

scheduler event queue list

spinlock_t lock

scheduler spinlock

wait_queue_head_t sched_wait_q

scheduler wait queue

struct ums_scheduler_proc_dirs dirs

scheduler procfs dirs

struct ums_event_node

UMS scheduler event node.

Public Members

struct ums_sched_event event
struct list_head list

Functions

int ums_scheduling_cache_create(void)

Create a slab cache for allocating UMS scheduling events.

Returns

  • 0 - OK

  • -ENOMEM - No memory available

void ums_scheduling_cache_destroy(void)

Destroy the slab cache for UMS scheduling events.

int enter_ums_scheduler_mode(struct ums_data *data, struct enter_ums_mode_args *args)

Enter UMS scheduling mode.

Creates a UMS scheduler and send a SCHEDULER_STARTUP event to it.

Context: Process context. May sleep. Takes and releases the RCU lock.

Parameters
  • data[in] pointer to the UMS data

  • args[in] userspace pointer for args

Returns

  • 0 - OK

  • -ENOMEM - No memory available

  • -EINVAL - Invalid UMS completion list arg

struct ums_event_node *alloc_ums_event(void)

Allocate an UMS scheduling event from the dedicated slab cache.

Returns

the UMS scheduling event

void free_ums_event(struct ums_event_node *event)

Deallocate the UMS scheduling event.

void enqueue_ums_sched_event(struct ums_scheduler *scheduler, struct ums_event_node *event, unsigned int flags)

Enqueue the UMS scheduling event to the UMS scheduler queue.

Context: Process context. Takes and releases scheduler->lock

Parameters
  • scheduler[in] pointer to the UMS scheduler

  • event[in] pointer to the UMS scheduling event

  • flags[in] flags specifying how to add the event (can be one from EVENT_ADD_HEAD or EVENT_ADD_TAIL)

void ums_scheduler_destroy(struct ums_scheduler *sched)

Destroy the UMS scheduler and every UMS scheduling event associated with it.

Context: Process context. Takes and releases scheduler->lock

Parameters
  • sched[in] pointer to the UMS scheduler

int exec_ums_context(struct ums_data *data, pid_t worker_pid)

Execute a UMS worker context.

Suspend the UMS scheduler switching its context with the UMS worker’s one.

Context: Process context. May sleep. Takes and releases the RCU lock.

Parameters
  • data[in] pointer to the UMS data

  • worker_pid[in] pid of the UMS worker

Returns

  • 0 - OK

  • -ESRCH - Bad worker pid or bad UMS calling thread