proc: add some (hopefully) insightful comments
* /proc/${pid}/net status * removing PDE vs last close stuff (again!) * random small stuff Link: https://lkml.kernel.org/r/YtwrM6sDC0OQ53YB@localhost.localdomain Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
parent
fa7d574ba4
commit
ed8fb78d7e
@ -99,6 +99,10 @@ void proc_task_name(struct seq_file *m, struct task_struct *p, bool escape)
|
|||||||
{
|
{
|
||||||
char tcomm[64];
|
char tcomm[64];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Test before PF_KTHREAD because all workqueue worker threads are
|
||||||
|
* kernel threads.
|
||||||
|
*/
|
||||||
if (p->flags & PF_WQ_WORKER)
|
if (p->flags & PF_WQ_WORKER)
|
||||||
wq_worker_comm(tcomm, sizeof(tcomm), p);
|
wq_worker_comm(tcomm, sizeof(tcomm), p);
|
||||||
else if (p->flags & PF_KTHREAD)
|
else if (p->flags & PF_KTHREAD)
|
||||||
|
@ -212,7 +212,15 @@ static void unuse_pde(struct proc_dir_entry *pde)
|
|||||||
complete(pde->pde_unload_completion);
|
complete(pde->pde_unload_completion);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* pde is locked on entry, unlocked on exit */
|
/*
|
||||||
|
* At most 2 contexts can enter this function: the one doing the last
|
||||||
|
* close on the descriptor and whoever is deleting PDE itself.
|
||||||
|
*
|
||||||
|
* First to enter calls ->proc_release hook and signals its completion
|
||||||
|
* to the second one which waits and then does nothing.
|
||||||
|
*
|
||||||
|
* PDE is locked on entry, unlocked on exit.
|
||||||
|
*/
|
||||||
static void close_pdeo(struct proc_dir_entry *pde, struct pde_opener *pdeo)
|
static void close_pdeo(struct proc_dir_entry *pde, struct pde_opener *pdeo)
|
||||||
__releases(&pde->pde_unload_lock)
|
__releases(&pde->pde_unload_lock)
|
||||||
{
|
{
|
||||||
@ -222,9 +230,6 @@ static void close_pdeo(struct proc_dir_entry *pde, struct pde_opener *pdeo)
|
|||||||
*
|
*
|
||||||
* rmmod (remove_proc_entry() et al) can't delete an entry and proceed:
|
* rmmod (remove_proc_entry() et al) can't delete an entry and proceed:
|
||||||
* "struct file" needs to be available at the right moment.
|
* "struct file" needs to be available at the right moment.
|
||||||
*
|
|
||||||
* Therefore, first process to enter this function does ->release() and
|
|
||||||
* signals its completion to the other process which does nothing.
|
|
||||||
*/
|
*/
|
||||||
if (pdeo->closing) {
|
if (pdeo->closing) {
|
||||||
/* somebody else is doing that, just wait */
|
/* somebody else is doing that, just wait */
|
||||||
@ -238,10 +243,12 @@ static void close_pdeo(struct proc_dir_entry *pde, struct pde_opener *pdeo)
|
|||||||
|
|
||||||
pdeo->closing = true;
|
pdeo->closing = true;
|
||||||
spin_unlock(&pde->pde_unload_lock);
|
spin_unlock(&pde->pde_unload_lock);
|
||||||
|
|
||||||
file = pdeo->file;
|
file = pdeo->file;
|
||||||
pde->proc_ops->proc_release(file_inode(file), file);
|
pde->proc_ops->proc_release(file_inode(file), file);
|
||||||
|
|
||||||
spin_lock(&pde->pde_unload_lock);
|
spin_lock(&pde->pde_unload_lock);
|
||||||
/* After ->release. */
|
/* Strictly after ->proc_release, see above. */
|
||||||
list_del(&pdeo->lh);
|
list_del(&pdeo->lh);
|
||||||
c = pdeo->c;
|
c = pdeo->c;
|
||||||
spin_unlock(&pde->pde_unload_lock);
|
spin_unlock(&pde->pde_unload_lock);
|
||||||
|
@ -350,6 +350,12 @@ static __net_init int proc_net_ns_init(struct net *net)
|
|||||||
kgid_t gid;
|
kgid_t gid;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This PDE acts only as an anchor for /proc/${pid}/net hierarchy.
|
||||||
|
* Corresponding inode (PDE(inode) == net->proc_net) is never
|
||||||
|
* instantiated therefore blanket zeroing is fine.
|
||||||
|
* net->proc_net_stat inode is instantiated normally.
|
||||||
|
*/
|
||||||
err = -ENOMEM;
|
err = -ENOMEM;
|
||||||
netd = kmem_cache_zalloc(proc_dir_entry_cache, GFP_KERNEL);
|
netd = kmem_cache_zalloc(proc_dir_entry_cache, GFP_KERNEL);
|
||||||
if (!netd)
|
if (!netd)
|
||||||
|
@ -302,6 +302,11 @@ void __init proc_root_init(void)
|
|||||||
proc_mkdir("bus", NULL);
|
proc_mkdir("bus", NULL);
|
||||||
proc_sys_init();
|
proc_sys_init();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Last things last. It is not like userspace processes eager
|
||||||
|
* to open /proc files exist at this point but register last
|
||||||
|
* anyway.
|
||||||
|
*/
|
||||||
register_filesystem(&proc_fs_type);
|
register_filesystem(&proc_fs_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user