Documentation/translations/zh_CN/core-api/padata.rst

Source file repositories/reference/linux-study-clean/Documentation/translations/zh_CN/core-api/padata.rst

File Facts

System
Linux kernel
Corpus path
Documentation/translations/zh_CN/core-api/padata.rst
Extension
.rst
Size
7086 bytes
Lines
162
Domain
Support Tooling And Documentation
Bucket
Documentation
Inferred role
Support Tooling And Documentation: documentation
Status
atlas-only

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

struct padata_priv {
        /* Other stuff here... */
	void                    (*parallel)(struct padata_priv *padata);
	void                    (*serial)(struct padata_priv *padata);
    };

这个结构体几乎肯定会被嵌入到一些针对要做的工作的大结构体中。它的大部分字段对
padata来说是私有的,但是这个结构在初始化时应该被清零,并且应该提供parallel()和
serial()函数。在完成工作的过程中,这些函数将被调用,我们马上就会遇到。

工作的提交是通过::

    int padata_do_parallel(struct padata_shell *ps,
		           struct padata_priv *padata, int *cb_cpu);

ps和padata结构体必须如上所述进行设置;cb_cpu指向作业完成后用于最终回调的首选CPU;
它必须在当前实例的CPU掩码中(如果不是,cb_cpu指针将被更新为指向实际选择的CPU)。
padata_do_parallel()的返回值在成功时为0,表示工作正在进行中。-EBUSY意味着有人
在其他地方正在搞乱实例的CPU掩码,而当cb_cpu不在串行cpumask中、并行或串行cpumasks
中无在线CPU,或实例停止时,则会出现-EINVAL反馈。

每个提交给padata_do_parallel()的作业将依次传递给一个CPU上的上述parallel()函数
的一个调用,所以真正的并行是通过提交多个作业来实现的。parallel()在运行时禁用软
件中断,因此不能睡眠。parallel()函数把获得的padata_priv结构体指针作为其唯一的参
数;关于实际要做的工作的信息可能是通过使用container_of()找到封装结构体来获得的。

请注意,parallel()没有返回值;padata子系统假定parallel()将从此时开始负责这项工
作。作业不需要在这次调用中完成,但是,如果parallel()留下了未完成的工作,它应该准
备在前一个作业完成之前,被以新的作业再次调用

序列化作业
----------

当一个作业完成时,parallel()(或任何实际完成该工作的函数)应该通过调用通知padata此
事::

    void padata_do_serial(struct padata_priv *padata);

在未来的某个时刻,padata_do_serial()将触发对padata_priv结构体中serial()函数的调
用。这个调用将发生在最初要求调用padata_do_parallel()的CPU上;它也是在本地软件中断
被禁用的情况下运行的。
请注意,这个调用可能会被推迟一段时间,因为padata代码会努力确保作业按照提交的顺序完
成。

销毁
----

清理一个padata实例时,可以预见的是调用两个free函数,这两个函数对应于分配的逆过程::

    void padata_free_shell(struct padata_shell *ps);
    void padata_free(struct padata_instance *pinst);

用户有责任确保在调用上述任何一项之前,所有未完成的工作都已完成。

运行多线程作业
==============

一个多线程作业有一个主线程和零个或多个辅助线程,主线程参与作业,然后等待所有辅助线
程完成。padata将作业分割成称为chunk的单元,其中chunk是一个线程在一次调用线程函数
中完成的作业片段。

用户必须做三件事来运行一个多线程作业。首先,通过定义一个padata_mt_job结构体来描述
作业,这在接口部分有解释。这包括一个指向线程函数的指针,padata每次将作业块分配给线
程时都会调用这个函数。然后,定义线程函数,它接受三个参数: ``start`` 、 ``end`` 和 ``arg`` ,
其中前两个参数限定了线程操作的范围,最后一个是指向作业共享状态的指针,如果有的话。
准备好共享状态,它通常被分配在主线程的堆栈中。最后,调用padata_do_multithreaded(),
它将在作业完成后返回。

接口
====

Annotation

Implementation Notes