RDT_Feature_Level (RDT特性级别)中文

本文深入解析RDT协议的特征,包括数据包结构、序列号管理、丢包处理机制及反馈机制等关键内容,并介绍了RDT_Feature_Level_304规格中的传输信息请求与响应包格式。

术语:
RTT:Round Trip Time是从一个包离开发送者到发送者接收
到接收者发送的对该包的响应所经历的时间。
一、RDT_Feature_Level_20

I. RDT data packets
    一个RDT stream有多个stream。每个packet在stream的序列号从0开始,到0xff00重复循环。因此stream_id和sequence number保证了packet的唯一性。
    is_reliable flag将stream指定为high priority or less loss tolerant的datatype。这些stream中有全局的second sequence number来表示所有is_reliable flag被置位的packet。这种second sequence number是由应用程序指定的。
    如果RDT data packet的length_included_flag被置位,则存在packet聚合——将多个packet放进一个UDP包。聚合的packet存 在length字段,方便客户端跳到下一个RDT header。在server端可以用--dpa命令禁止packet聚合。
-------------------------------------------------------------------------------
II. Packets lost before transport
    所有的RealNetworks datatype都可以忍受一定的丢包。如果encoder间server发生了不可重获的丢包,那么server无法将所有的packet都发给 client,这时server需要以所丢失包的序列号发送一个空包(没有payload data),则client知道发生了丢包而不会发送NAK packet。注意,在TCP模式下,server只是用序列号的间隙来表示丢包,因为丢包无疑是在传输之前产生的。
-------------------------------------------------------------------------------
Table C. RDT NAK/ACK PACKET

RDT NAK PACKET

    012    78               24        40     56        72
    +++----++---------------+------...+---...+------...+-------+
    |||    ||0xff02         |stream_id|seq_no|bit_count|map_len|
    +++----++---------------+------...+---...+------...+-------+
     ^
     |
     lost_high (1 for NAK)

- NAK packet的前三个字节总是0x40ff02
- NAK的bit_count和map_len总是0
- stream_id with seq_no指明了丢包位置
- lost_high是丢包指示位,在NAK中总是被置位
RDT ACK PACKET

                            |<---Repeated for each stream in session--->|
    012    78               24        40     56        72      80
    +++----++---------------+------...+---...+------...+-------+-----...+
    |||    ||0xff02         |stream id|seq_no|bit_count|map_len|bitfield|
    +++----++---------------+------...+---...+------...+-------+-----...+
     ^
     |
     lost_high (almost always 0 for ACK)

- lost_high在ACK中几乎从不置位.见section III.
- 每个stream一个data portion
- stream_id指示被ACK通知的stream
- seq_no是bitfield中的最高序列号.
- bit_count指示bitfield中的bit数目(packets being ACKed)
- map_len指示bitfield的byte数目(rounded up)
- There is one bitfield for every packet ACKed.  1 indicates packet was
  received.  0 indicates packet was not received.
III. Packets lost in transport
    client通过发送ACK/NAK packet来使数据恢复。client一旦发现序列号有间隙,就为每个缺少的序列号发送一个NAK packet。这意味着server将会为收到的乱序packet产生一个NAK。此外client每间隔一秒发送一个ACK packet。在ACK packet中,session中的每个stream对应一个bitfield,field中的1表示收到,0表示没有。server一旦收到NAK packet或者表示有丢包的ACK packet,就会重传相应的packet。所有标记为收到的packet会从server的缓冲区中清除掉。
    本文中所说的ACK/NAK packet实际上有相同的结构。它们的区别在于lost_high flag,这个标志位指明对应序列号的packet丢失了。ACK packet是基于收到的最高的序列号产生的,因此最高序列号的packet不会被认为是丢失了,而只是还没到达。
    唯一的例外是以下情况:a stream ACK的大小超过了最大bitset限制而只能用2个ACK packet发送,第一个ACK section中的最后一个ACK packet正好丢失了。最大bitset是48byte。因为每秒发送一个ACK,这种情况只发生在大于1.5Mbps的stream上。
IV. Identifying RDT data recovery on the wire
NAK packet总是以0x40ff02开始,每个丢掉的包产生一个;
ACK packet总是以0x00ff02开始,每秒产生一个;
用于传输前产生的丢包的Placeholder packets总是10字节长;
-------------------------------------------------------------------------------

Appendix - packet definitions and field summaries

(if expressions indicate differing packet formats based on values in static
fields)

packlen struct TNGDataPacket
{
    bit[1]                      length_included_flag;   /* Inc. length field
*/
    bit[1]                      need_reliable_flag;     /* Inc. rel. seq no */
    bit[5]                      stream_id;              /* 31 == expansion */
    bit[1]                      is_reliable;

    u_int16                     seq_no;         /* overload for packet type*/

    if(length_included_flag == 1)
    {
        u_int16                 rdt_packet_length; // payload length if
        // length flag is set
    }

    bit[1]                      back_to_back_packet;
    bit[1]                      slow_data;
    bit[6]                      asm_rule_number;        /* 63 is expansion */

    u_int32                     timestamp;
    if(stream_id == 31)
    {
        u_int16                 stream_id_expansion;
    }
    if(need_reliable_flag == 1)
    {
        u_int16                 total_reliable;
    }
    if(asm_rule_number == 63)
    {
        u_int16                 asm_rule_number_expansion;
    }
    buffer                      data;
}

- length_included_flag:指示packet聚合.当datagram大小未规定时,指示payload大小
- need_reliable_flag:总是置位
- stream_id:跟数据类型相关(usually 0 for audio, 1 for video)
  stream_id 31:保留为将来扩展之用,目前还未使用
- is_reliable:用于less tolerant to loss的数据
- seq_no:在0和0xff00之间循环.每个stream内有自己的seq_nos.
  高于0xff00的表示特殊packet类型(such as ACK 0xff02)
- back_to_back_packet:用于校时,每十个packet中有一个有效
- slow_data:保留为将来扩展之用,目前还未使用
- asm_rule_number:在SureStream与ASM rulebook in file headers共同作用,以使client可以根据带宽选择流.  asm_rule_number 63保留为将来扩展之用,目前还未使用
- timestamp:数据类型相关,按时间递增
- total_reliable:给定的stream中is_reliable被置位的packet的总和. 


struct TNGACKPacket
{
    bit[1]                      length_included_flag;
    bit[1]                      lost_high;
    bit[5]                      dummy0; /* 0 */
    bit[1]                      dummy1; /* 0 */
    u_int16                     packet_type; /* 0xff02 */
    if(length_included_flag == 1)
    {
        u_int16                 length;
    }
    /*
     * data consists of header + bitmap repeated for each stream:
     *   u_int16 stream_number
     *   u_int16 last_seq_no
     *   u_int16 bit_count
     *   u_int8  bitmap_length
     *   buffer bitmap
     */
    buffer                      data;
}

- length_included_flag:ACK中固定为0
- lost_high indicates that the sequence number in the data segment is
  a lost packet.  These packets have no ACK component.  These packets will only
  have a data segment for 1 stream.
- packet_type:对于ACK/NAK packets是0xff02.


二、RDT_Feature_Level_30
4 Specification
只有服务端和客户端的RTSP header同时支持RDTFeatureLevel时,此规格有效。

4.1 RDTTransportInfoRequestPacket

struct RDTTransportInfoRequestPacket
{
    bit[1]   dummy0; /* 0 */
    bit[5]   dummy1; /* 0 */
    bit[1]   request_rtt_info;
    bit[1]   request_buffer_info;
    u_int16   packet_type; /* 0xff09 */

    if (request_rtt_info == 1)
    {
        u_int32                     request_time_ms;
    }
}
    RDTTransportInfoRequestPacket用于请求传播时延和/或接收buffer状态。流的接收端和发送端都可以发出此请求,接收端 发出此请求时不能给request_buffer_info字段置位。此请求的发送方需要保证the traffic generated does
not exceed the feedback of delayed ACK TCP as specified in [ 9 ].此请求可以包含在其它RDT包中,但不能超过大小限制。


4.2 RDTTransportInfoResponsePacket

struct RDTBufferInfo
{
    u_int16  stream_id;
    u_int32  lowest_timestamp;
    u_int32  highest_timestamp;
    u_int32  bytes_buffered;
}

struct RDTTransportInfoResponsePacket
{
    bit[1]   dummy0; /* 0 */
    bit[4]   dummy1; /* 0 */
    bit[1]   has_rtt_info;
    bit[1]   is_delayed;
    bit[1]   has_buffer_info;
    u_int16   packet_type; /* 0xff0a */

    if (has_rtt_info == 1)
    {
        u_int32                     request_time_ms;
 if (is_delayed)
 {
     u_int32                     response_time_ms;
 }
    }
    if (has_buffer_info == 1)
    {
        u_int16 buffer_info_count;
        RDTBufferInfo[buffer_info_count] buffer_info;
    }
}
RDTTransportInfoResponsePacket是对RDTTransportInfoRequestPacket的响应.因为这些包是经由不可靠信道传送的,服务端不应该依赖于任何这些相应。

4.2.1 has_rtt_info response
response_time_ms表示从收到对应 request packet起经过的时间。packet接收方需要尽可能快地响应每一个request。

4.2.2 has_buffer_info response
    当response packet中的has_buffer_info被置位时,每一个stream对应一个RDTBufferInfo structure。stream的顺序对应于session的stream_id。RDTBufferInfo中的数据应该包括stream中所有还未 传至renderer的packet。对于bytes_buffered,接受方需要保证所有timestamp相同且等于 lowest_timestamp的packet都作为一个整体进行计算.bytes_buffered字段只包含payload data,没有任何传输相关的header。如果缓冲区的数据存在timestamp间隙,接收方需要在相应datagram包括一个 RDTNakPacket。如果缓冲区没有packet,接收方必须将最后送入renderer的packet的timestamp作为 highest_timestamp and lowest_timestamp;如果没有数据送入renderer,这两个字段都设为0。

4.3 Bandwidth Overhead for TransportInfo packets
4.4 Handling of NULL Packets
struct task_struct { #ifdef CONFIG_THREAD_INFO_IN_TASK /* * For reasons of header soup (see current_thread_info()), this * must be the first element of task_struct. */ struct thread_info thread_info; #endif /* -1 unrunnable, 0 runnable, >0 stopped: */ volatile long state; /* * This begins the randomizable portion of task_struct. Only * scheduling-critical items should be added above here. */ randomized_struct_fields_start void *stack; atomic_t usage; /* Per task flags (PF_*), defined further below: */ unsigned int flags; unsigned int ptrace; #ifdef CONFIG_SMP struct llist_node wake_entry; int on_cpu; #ifdef CONFIG_THREAD_INFO_IN_TASK /* Current CPU: */ unsigned int cpu; #endif unsigned int wakee_flips; unsigned long wakee_flip_decay_ts; struct task_struct *last_wakee; /* * recent_used_cpu is initially set as the last CPU used by a task * that wakes affine another task. Waker/wakee relationships can * push tasks around a CPU where each wakeup moves to the next one. * Tracking a recently used CPU allows a quick search for a recently * used CPU that may be idle. */ int recent_used_cpu; int wake_cpu; #endif int on_rq; int prio; int static_prio; int normal_prio; unsigned int rt_priority; const struct sched_class *sched_class; struct sched_entity se; struct sched_rt_entity rt; #ifdef CONFIG_CGROUP_SCHED struct task_group *sched_task_group; #endif struct sched_dl_entity dl; #ifdef CONFIG_PREEMPT_NOTIFIERS /* List of struct preempt_notifier: */ struct hlist_head preempt_notifiers; #endif #ifdef CONFIG_BLK_DEV_IO_TRACE unsigned int btrace_seq; #endif unsigned int policy; int nr_cpus_allowed; cpumask_t cpus_allowed; #ifdef CONFIG_PREEMPT_RCU int rcu_read_lock_nesting; union rcu_special rcu_read_unlock_special; struct list_head rcu_node_entry; struct rcu_node *rcu_blocked_node; #endif /* #ifdef CONFIG_PREEMPT_RCU */ #ifdef CONFIG_TASKS_RCU unsigned long rcu_tasks_nvcsw; u8 rcu_tasks_holdout; u8 rcu_tasks_idx; int rcu_tasks_idle_cpu; struct list_head rcu_tasks_holdout_list; #endif /* #ifdef CONFIG_TASKS_RCU */ struct sched_info sched_info; struct list_head tasks; #ifdef CONFIG_SMP struct plist_node pushable_tasks; struct rb_node pushable_dl_tasks; #endif struct mm_struct *mm; struct mm_struct *active_mm; /* Per-thread vma caching: */ struct vmacache vmacache; int exit_state; int exit_code; int exit_signal; /* The signal sent when the parent dies: */ int pdeath_signal; /* JOBCTL_*, siglock protected: */ unsigned long jobctl; /* Used for emulating ABI behavior of previous Linux versions: */ unsigned int personality; /* Scheduler bits, serialized by scheduler locks: */ unsigned sched_reset_on_fork:1; unsigned sched_contributes_to_load:1; unsigned sched_migrated:1; unsigned sched_remote_wakeup:1; /* Force alignment to the next boundary: */ unsigned :0; /* Unserialized, strictly 'current' */ /* Bit to tell LSMs we're in execve(): */ unsigned in_execve:1; unsigned in_iowait:1; #ifndef TIF_RESTORE_SIGMASK unsigned restore_sigmask:1; #endif #ifdef CONFIG_MEMCG unsigned in_user_fault:1; #ifdef CONFIG_MEMCG_KMEM unsigned memcg_kmem_skip_account:1; #endif #endif #ifdef CONFIG_COMPAT_BRK unsigned brk_randomized:1; #endif #ifdef CONFIG_CGROUPS /* disallow userland-initiated cgroup migration */ unsigned no_cgroup_migration:1; /* task is frozen/stopped (used by the cgroup freezer) */ unsigned frozen:1; #endif #ifdef CONFIG_BLK_CGROUP /* to be used once the psi infrastructure lands upstream. */ unsigned use_memdelay:1; #endif unsigned long atomic_flags; /* Flags requiring atomic access. */ struct restart_block restart_block; pid_t pid; pid_t tgid; #ifdef CONFIG_SECURITY_KYSEC_AUTHENTICATION void *kysec_fop; #endif #ifdef CONFIG_STACKPROTECTOR /* Canary value for the -fstack-protector GCC feature: */ unsigned long stack_canary; #endif /* * Pointers to the (original) parent process, youngest child, younger sibling, * older sibling, respectively. (p->father can be replaced with * p->real_parent->pid) */ /* Real parent process: */ struct task_struct __rcu *real_parent; /* Recipient of SIGCHLD, wait4() reports: */ struct task_struct __rcu *parent; /* * Children/sibling form the list of natural children: */ struct list_head children; struct list_head sibling; struct task_struct *group_leader; /* * 'ptraced' is the list of tasks this task is using ptrace() on. * * This includes both natural children and PTRACE_ATTACH targets. * 'ptrace_entry' is this task's link on the p->parent->ptraced list. */ struct list_head ptraced; struct list_head ptrace_entry; /* PID/PID hash table linkage. */ struct pid *thread_pid; struct hlist_node pid_links[PIDTYPE_MAX]; struct list_head thread_group; struct list_head thread_node; struct completion *vfork_done; /* CLONE_CHILD_SETTID: */ int __user *set_child_tid; /* CLONE_CHILD_CLEARTID: */ int __user *clear_child_tid; u64 utime; u64 stime; #ifdef CONFIG_ARCH_HAS_SCALED_CPUTIME u64 utimescaled; u64 stimescaled; #endif u64 gtime; struct prev_cputime prev_cputime; #ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN struct vtime vtime; #endif #ifdef CONFIG_NO_HZ_FULL atomic_t tick_dep_mask; #endif /* Context switch counts: */ unsigned long nvcsw; unsigned long nivcsw; /* Monotonic time in nsecs: */ u64 start_time; /* Boot based time in nsecs: */ u64 real_start_time; /* MM fault and swap info: this can arguably be seen as either mm-specific or thread-specific: */ unsigned long min_flt; unsigned long maj_flt; #ifdef CONFIG_POSIX_TIMERS struct task_cputime cputime_expires; struct list_head cpu_timers[3]; #endif /* Process credentials: */ /* Tracer's credentials at attach: */ const struct cred __rcu *ptracer_cred; /* Objective and real subjective task credentials (COW): */ const struct cred __rcu *real_cred; /* Effective (overridable) subjective task credentials (COW): */ const struct cred __rcu *cred; /* * executable name, excluding path. * * - normally initialized setup_new_exec() * - access it with [gs]et_task_comm() * - lock it with task_lock() */ char comm[TASK_COMM_LEN]; struct nameidata *nameidata; #ifdef CONFIG_SYSVIPC struct sysv_sem sysvsem; struct sysv_shm sysvshm; #endif #ifdef CONFIG_DETECT_HUNG_TASK unsigned long last_switch_count; unsigned long last_switch_time; #endif /* Filesystem information: */ struct fs_struct *fs; /* Open file information: */ struct files_struct *files; #ifdef CONFIG_IO_URING struct io_uring_task *io_uring; #endif /* Namespaces: */ struct nsproxy *nsproxy; /* Signal handlers: */ struct signal_struct *signal; struct sighand_struct *sighand; sigset_t blocked; sigset_t real_blocked; /* Restored if set_restore_sigmask() was used: */ sigset_t saved_sigmask; struct sigpending pending; unsigned long sas_ss_sp; size_t sas_ss_size; unsigned int sas_ss_flags; struct callback_head *task_works; struct audit_context *audit_context; #ifdef CONFIG_AUDITSYSCALL kuid_t loginuid; unsigned int sessionid; #endif struct seccomp seccomp; /* Thread group tracking: */ u64 parent_exec_id; u64 self_exec_id; /* Protection against (de-)allocation: mm, files, fs, tty, keyrings, mems_allowed, mempolicy: */ spinlock_t alloc_lock; /* Protection of the PI data structures: */ raw_spinlock_t pi_lock; struct wake_q_node wake_q; #ifdef CONFIG_RT_MUTEXES /* PI waiters blocked on a rt_mutex held by this task: */ struct rb_root_cached pi_waiters; /* Updated under owner's pi_lock and rq lock */ struct task_struct *pi_top_task; /* Deadlock detection and priority inheritance handling: */ struct rt_mutex_waiter *pi_blocked_on; #endif #ifdef CONFIG_DEBUG_MUTEXES /* Mutex deadlock detection: */ struct mutex_waiter *blocked_on; #endif #ifdef CONFIG_TRACE_IRQFLAGS unsigned int irq_events; unsigned long hardirq_enable_ip; unsigned long hardirq_disable_ip; unsigned int hardirq_enable_event; unsigned int hardirq_disable_event; int hardirqs_enabled; int hardirq_context; u64 hardirq_chain_key; unsigned long softirq_disable_ip; unsigned long softirq_enable_ip; unsigned int softirq_disable_event; unsigned int softirq_enable_event; int softirqs_enabled; int softirq_context; #endif #ifdef CONFIG_LOCKDEP # define MAX_LOCK_DEPTH 48UL u64 curr_chain_key; int lockdep_depth; unsigned int lockdep_recursion; struct held_lock held_locks[MAX_LOCK_DEPTH]; #endif #ifdef CONFIG_UBSAN unsigned int in_ubsan; #endif /* Journalling filesystem info: */ void *journal_info; /* Stacked block device info: */ struct bio_list *bio_list; #ifdef CONFIG_BLOCK /* Stack plugging: */ struct blk_plug *plug; #endif /* VM state: */ struct reclaim_state *reclaim_state; struct backing_dev_info *backing_dev_info; struct io_context *io_context; /* Ptrace state: */ unsigned long ptrace_message; siginfo_t *last_siginfo; struct task_io_accounting ioac; #ifdef CONFIG_TASK_XACCT /* Accumulated RSS usage: */ u64 acct_rss_mem1; /* Accumulated virtual memory usage: */ u64 acct_vm_mem1; /* stime + utime since last update: */ u64 acct_timexpd; #endif #ifdef CONFIG_CPUSETS /* Protected by ->alloc_lock: */ nodemask_t mems_allowed; /* Seqence number to catch updates: */ seqcount_t mems_allowed_seq; int cpuset_mem_spread_rotor; int cpuset_slab_spread_rotor; #endif #ifdef CONFIG_CGROUPS /* Control Group info protected by css_set_lock: */ struct css_set __rcu *cgroups; /* cg_list protected by css_set_lock and tsk->alloc_lock: */ struct list_head cg_list; #endif #if defined(CONFIG_RESCTRL) || defined(CONFIG_INTEL_RDT) u32 closid; u32 rmid; #endif #ifdef CONFIG_FUTEX struct robust_list_head __user *robust_list; #ifdef CONFIG_COMPAT struct compat_robust_list_head __user *compat_robust_list; #endif struct list_head pi_state_list; struct futex_pi_state *pi_state_cache; struct mutex futex_exit_mutex; unsigned int futex_state; #endif #ifdef CONFIG_PERF_EVENTS struct perf_event_context *perf_event_ctxp[perf_nr_task_contexts]; struct mutex perf_event_mutex; struct list_head perf_event_list; #endif #ifdef CONFIG_DEBUG_PREEMPT unsigned long preempt_disable_ip; #endif #ifdef CONFIG_NUMA /* Protected by alloc_lock: */ struct mempolicy *mempolicy; short il_prev; short pref_node_fork; #endif #ifdef CONFIG_NUMA_BALANCING int numa_scan_seq; unsigned int numa_scan_period; unsigned int numa_scan_period_max; int numa_preferred_nid; unsigned long numa_migrate_retry; /* Migration stamp: */ u64 node_stamp; u64 last_task_numa_placement; u64 last_sum_exec_runtime; struct callback_head numa_work; /* * This pointer is only modified for current in syscall and * pagefault context (and for tasks being destroyed), so it can be read * from any of the following contexts: * - RCU read-side critical section * - current->numa_group from everywhere * - task's runqueue locked, task not running */ struct numa_group __rcu *numa_group; /* * numa_faults is an array split into four regions: * faults_memory, faults_cpu, faults_memory_buffer, faults_cpu_buffer * in this precise order. * * faults_memory: Exponential decaying average of faults on a per-node * basis. Scheduling placement decisions are made based on these * counts. The values remain static for the duration of a PTE scan. * faults_cpu: Track the nodes the process was running on when a NUMA * hinting fault was incurred. * faults_memory_buffer and faults_cpu_buffer: Record faults per node * during the current scan window. When the scan completes, the counts * in faults_memory and faults_cpu decay and these values are copied. */ unsigned long *numa_faults; unsigned long total_numa_faults; /* * numa_faults_locality tracks if faults recorded during the last * scan window were remote/local or failed to migrate. The task scan * period is adapted based on the locality of the faults with different * weights depending on whether they were shared or private faults */ unsigned long numa_faults_locality[3]; unsigned long numa_pages_migrated; #endif /* CONFIG_NUMA_BALANCING */ #ifdef CONFIG_RSEQ struct rseq __user *rseq; u32 rseq_len; u32 rseq_sig; /* * RmW on rseq_event_mask must be performed atomically * with respect to preemption. */ unsigned long rseq_event_mask; #endif struct tlbflush_unmap_batch tlb_ubc; #ifndef __GENKSYMS__ union { refcount_t rcu_users; struct rcu_head rcu; }; #else struct rcu_head rcu; #endif /* Cache last used pipe for splice(): */ struct pipe_inode_info *splice_pipe; struct page_frag task_frag; #ifdef CONFIG_TASK_DELAY_ACCT struct task_delay_info *delays; #endif #ifdef CONFIG_FAULT_INJECTION int make_it_fail; unsigned int fail_nth; #endif /* * When (nr_dirtied >= nr_dirtied_pause), it's time to call * balance_dirty_pages() for a dirty throttling pause: */ int nr_dirtied; int nr_dirtied_pause; /* Start of a write-and-pause period: */ unsigned long dirty_paused_when; #ifdef CONFIG_LATENCYTOP int latency_record_count; struct latency_record latency_record[LT_SAVECOUNT]; #endif /* * Time slack values; these are used to round up poll() and * select() etc timeout values. These are in nanoseconds. */ u64 timer_slack_ns; u64 default_timer_slack_ns; #ifdef CONFIG_KASAN unsigned int kasan_depth; #endif #ifdef CONFIG_KCSAN struct kcsan_ctx kcsan_ctx; #endif #ifdef CONFIG_FUNCTION_GRAPH_TRACER /* Index of current stored address in ret_stack: */ int curr_ret_stack; int curr_ret_depth; /* Stack of return addresses for return function tracing: */ struct ftrace_ret_stack *ret_stack; /* Timestamp for last schedule: */ unsigned long long ftrace_timestamp; /* * Number of functions that haven't been traced * because of depth overrun: */ atomic_t trace_overrun; /* Pause tracing: */ atomic_t tracing_graph_pause; #endif #ifdef CONFIG_TRACING /* State flags for use by tracers: */ unsigned long trace; /* Bitmask and counter of trace recursion: */ unsigned long trace_recursion; #endif /* CONFIG_TRACING */ #ifdef CONFIG_KCOV /* Coverage collection mode enabled for this task (0 if disabled): */ unsigned int kcov_mode; /* Size of the kcov_area: */ unsigned int kcov_size; /* Buffer for coverage collection: */ void *kcov_area; /* KCOV descriptor wired with this task or NULL: */ struct kcov *kcov; #endif #ifdef CONFIG_MEMCG struct mem_cgroup *memcg_in_oom; gfp_t memcg_oom_gfp_mask; int memcg_oom_order; /* Number of pages to reclaim on returning to userland: */ unsigned int memcg_nr_pages_over_high; /* Used by memcontrol for targeted memcg charge: */ struct mem_cgroup *active_memcg; #endif #ifdef CONFIG_BLK_CGROUP struct request_queue *throttle_queue; #endif #ifdef CONFIG_UPROBES struct uprobe_task *utask; #endif #if defined(CONFIG_BCACHE) || defined(CONFIG_BCACHE_MODULE) unsigned int sequential_io; unsigned int sequential_io_avg; #endif #ifdef CONFIG_DEBUG_ATOMIC_SLEEP unsigned long task_state_change; #endif int pagefault_disabled; #ifdef CONFIG_MMU struct task_struct *oom_reaper_list; #endif #ifdef CONFIG_VMAP_STACK struct vm_struct *stack_vm_area; #endif #ifdef CONFIG_THREAD_INFO_IN_TASK /* A live task holds one reference: */ atomic_t stack_refcount; #endif #ifdef CONFIG_LIVEPATCH int patch_state; #endif #ifdef CONFIG_SECURITY /* Used by LSM modules for access restriction: */ void *security; #endif #ifdef CONFIG_BPF_SYSCALL /* Used for BPF run context */ struct bpf_run_ctx *bpf_ctx; #endif /* * New fields for task_struct should be added above here, so that * they are included in the randomized portion of task_struct. */ randomized_struct_fields_end unsigned int task_iowait_count; unsigned int task_io_quirk; unsigned long iowait_flip_decay_ts; unsigned long task_io_record_ts; struct cpumask preferred_io_cpumask; #ifdef CONFIG_QOS_SCHED_SMT_EXPELLER long qos_level; #endif unsigned long interactive_app; unsigned long task_section_flag; cpumask_t *prefer_cpus; const cpumask_t *select_cpus; #ifdef CONFIG_QOS_SCHED_SMART_GRID struct sched_grid_qos *grid_qos; #endif KABI_RESERVE(1) KABI_RESERVE(2) KABI_RESERVE(3) KABI_RESERVE(4) #ifdef CONFIG_PID_RESERVE KY_KABI_USE(5, fork_pid_t fork_pid_union) #else KABI_RESERVE(5) #endif KY_KABI_USE(6, unsigned long last_pipe_waketime); KABI_RESERVE(7) KABI_RESERVE(8) KY_KABI_REPLACE_SPLIT(long rh_reserved[64], int ky_kabi_dummy, /* 0 */ /* Use this one first */ ) /* CPU-specific state of this task: */ struct thread_struct thread; /* * WARNING: on x86, 'thread_struct' contains a variable-sized * structure. It *MUST* be at the end of 'task_struct'. * * Do not put anything below here! */ };
08-15
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值