UMS Completion List

Overview

The life cycle of a UMS completion list is bounded to the process that opens the UMS device and it is represented by the ums_complist structure. Once created it is stored inside the pool of completion lists pointed by ums_data.comp_lists. The completion list pool is based on a idr_l structure where a new ID is allocated for every completion list and it is then used for retrieving a completion list.

The memory allocated for the ums_complist structure is managed through its ums_complist.refcount and ums_complist.rhead: everyone who needs a reference to the completion list has to increment its reference counter and decrement it when it has finished using the completion list; when the reference counter of the completion list reaches zero the memory allocated to it is released through a call_rcu directive.

The list of UMS worker’s contexts associated with a particular UMS completion list is pointed by ums_complist.head; when an UMS scheduler dequeues the UMS workers from a completion list its ums_complist.head is transferred to the first UMS worker’s context of the list who becomes the new handler for retrieving the next UMS worker’s contexts.

Defines

COMPLIST_ADD_HEAD

Add a UMS context to the head of the UMS completion list

COMPLIST_ADD_TAIL

Add a UMS context to the tail of the UMS completion list

Structs

struct ums_complist

UMS completion list structure

Public Members

ums_comp_list_id_t id

UMS completion list id

struct list_head head

list head to first UMS context

spinlock_t lock
wait_queue_head_t wait_q

wait queue for dequeuing UMS contexts

struct kref refcount

Reference counter

struct rcu_head rhead

rcu head

struct ums_data *data

pointer to UMS device private data where this context belongs to

Functions

int create_ums_complist(struct ums_data *data, ums_comp_list_id_t *id)

Create a UMS completion list.

Allocates a ums_complist and initialize all its data structures.

The ums_complist::refcount counter is incremented and its ums_complist::id is passed to the user.

Context: Process context. May sleep.

Parameters
  • data[in] pointer to the UMS data

  • id[in] userspace pointer to the completion list id

Returns

  • 0 - OK

  • -ENOMEM - No memory available

  • -EACCESS - Bad userspace pointer

void ums_completion_list_add(struct ums_complist *complist, struct ums_context *context, unsigned int flags)

Add a UMS context to a UMS completion list.

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

Parameters
  • complist[in] pointer to the UMS completion list

  • context[in] pointer to the UMS worker context

  • flags[in] flags specifying how to add the context (can be one from COMPLIST_ADD_HEAD or COMPLIST_ADD_TAIL)

int ums_complist_dqcontext(struct ums_data *data, struct dequeue_ums_complist_args *args)

Retrieve a UMS context from a UMS completion list.

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

Parameters
  • data[in] pointer to the UMS private data

  • args[in] Userspace pointer for args

Returns

  • 0 - OK

  • -EACCESS - Bad userspace pointer

  • -EINVAL - Bad completion list id

  • -ESRCH - Bad UMS calling thread

  • -EINTR - Interrupted call

int ums_complist_next_context(struct ums_data *data, struct ums_next_context_list_args *args)

Retrieve the next UMS context from a UMS thread list.

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

Parameters
  • data[in] pointer to the UMS private data

  • args[in] Userspace pointer for args

Returns

  • 0 - OK

  • -EACCESS - Bad userspace pointer

  • -ESRCH - Bad UMS context

static struct ums_complist *get_ums_complist(struct ums_complist *c)

Increment the UMS completion list reference counter.

Context: Any context.

Parameters
  • c[in] pointer to the UMS completion list

Returns

the UMS completion list

int put_ums_complist(struct ums_complist *complist)

Decrement the UMS completion list reference counter and destroy it if the counter reaches zero.

Context: Any context.

Parameters
  • complist[in] pointer to the UMS completion list

Returns

1 if the completion list is destroyed, 0 otherwise.

int ums_complist_delete(struct ums_data *data, ums_comp_list_id_t complist_id)

Delete the UMS completion list.

Decrement the UMS completion list reference counter and destroy it if the counter reaches zero.

Context: Any context. Takes and releases the RCU lock.

Parameters
  • data[in] pointer to the UMS private data

  • complist_id[in] id of the UMS completion list

Returns

  • 0 - OK

  • -EINVAL - Bad UMS completion list id