mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	trimming task_work: kill ->data
get rid of the only user of ->data; this is _not_ the final variant - in the end we'll have task_work and rcu_head identical and just use cred->rcu, at which point the separate allocation will be gone completely. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
		
							parent
							
								
									7266702805
								
							
						
					
					
						commit
						41f9d29f09
					
				
					 5 changed files with 17 additions and 12 deletions
				
			
		| 
						 | 
					@ -10,14 +10,12 @@ typedef void (*task_work_func_t)(struct task_work *);
 | 
				
			||||||
struct task_work {
 | 
					struct task_work {
 | 
				
			||||||
	struct hlist_node hlist;
 | 
						struct hlist_node hlist;
 | 
				
			||||||
	task_work_func_t func;
 | 
						task_work_func_t func;
 | 
				
			||||||
	void *data;
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline void
 | 
					static inline void
 | 
				
			||||||
init_task_work(struct task_work *twork, task_work_func_t func, void *data)
 | 
					init_task_work(struct task_work *twork, task_work_func_t func)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	twork->func = func;
 | 
						twork->func = func;
 | 
				
			||||||
	twork->data = data;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int task_work_add(struct task_struct *task, struct task_work *twork, bool);
 | 
					int task_work_add(struct task_struct *task, struct task_work *twork, bool);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -830,7 +830,7 @@ static int irq_thread(void *data)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sched_setscheduler(current, SCHED_FIFO, ¶m);
 | 
						sched_setscheduler(current, SCHED_FIFO, ¶m);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	init_task_work(&on_exit_work, irq_thread_dtor, NULL);
 | 
						init_task_work(&on_exit_work, irq_thread_dtor);
 | 
				
			||||||
	task_work_add(current, &on_exit_work, false);
 | 
						task_work_add(current, &on_exit_work, false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	while (!irq_wait_for_interrupt(action)) {
 | 
						while (!irq_wait_for_interrupt(action)) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -148,6 +148,10 @@ extern key_ref_t lookup_user_key(key_serial_t id, unsigned long flags,
 | 
				
			||||||
#define KEY_LOOKUP_PARTIAL	0x02
 | 
					#define KEY_LOOKUP_PARTIAL	0x02
 | 
				
			||||||
#define KEY_LOOKUP_FOR_UNLINK	0x04
 | 
					#define KEY_LOOKUP_FOR_UNLINK	0x04
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct kludge {	/* this will die off very soon */
 | 
				
			||||||
 | 
						struct task_work twork;
 | 
				
			||||||
 | 
						struct cred *cred;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
extern long join_session_keyring(const char *name);
 | 
					extern long join_session_keyring(const char *name);
 | 
				
			||||||
extern void key_change_session_keyring(struct task_work *twork);
 | 
					extern void key_change_session_keyring(struct task_work *twork);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1456,7 +1456,8 @@ long keyctl_session_to_parent(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct task_struct *me, *parent;
 | 
						struct task_struct *me, *parent;
 | 
				
			||||||
	const struct cred *mycred, *pcred;
 | 
						const struct cred *mycred, *pcred;
 | 
				
			||||||
	struct task_work *newwork, *oldwork;
 | 
						struct kludge *newwork;
 | 
				
			||||||
 | 
						struct task_work *oldwork;
 | 
				
			||||||
	key_ref_t keyring_r;
 | 
						key_ref_t keyring_r;
 | 
				
			||||||
	struct cred *cred;
 | 
						struct cred *cred;
 | 
				
			||||||
	int ret;
 | 
						int ret;
 | 
				
			||||||
| 
						 | 
					@ -1466,7 +1467,7 @@ long keyctl_session_to_parent(void)
 | 
				
			||||||
		return PTR_ERR(keyring_r);
 | 
							return PTR_ERR(keyring_r);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = -ENOMEM;
 | 
						ret = -ENOMEM;
 | 
				
			||||||
	newwork = kmalloc(sizeof(struct task_work), GFP_KERNEL);
 | 
						newwork = kmalloc(sizeof(struct kludge), GFP_KERNEL);
 | 
				
			||||||
	if (!newwork)
 | 
						if (!newwork)
 | 
				
			||||||
		goto error_keyring;
 | 
							goto error_keyring;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1478,7 +1479,8 @@ long keyctl_session_to_parent(void)
 | 
				
			||||||
		goto error_newwork;
 | 
							goto error_newwork;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cred->tgcred->session_keyring = key_ref_to_ptr(keyring_r);
 | 
						cred->tgcred->session_keyring = key_ref_to_ptr(keyring_r);
 | 
				
			||||||
	init_task_work(newwork, key_change_session_keyring, cred);
 | 
						init_task_work(&newwork->twork, key_change_session_keyring);
 | 
				
			||||||
 | 
						newwork->cred = cred;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	me = current;
 | 
						me = current;
 | 
				
			||||||
	rcu_read_lock();
 | 
						rcu_read_lock();
 | 
				
			||||||
| 
						 | 
					@ -1527,18 +1529,18 @@ long keyctl_session_to_parent(void)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* the replacement session keyring is applied just prior to userspace
 | 
						/* the replacement session keyring is applied just prior to userspace
 | 
				
			||||||
	 * restarting */
 | 
						 * restarting */
 | 
				
			||||||
	ret = task_work_add(parent, newwork, true);
 | 
						ret = task_work_add(parent, &newwork->twork, true);
 | 
				
			||||||
	if (!ret)
 | 
						if (!ret)
 | 
				
			||||||
		newwork = NULL;
 | 
							newwork = NULL;
 | 
				
			||||||
unlock:
 | 
					unlock:
 | 
				
			||||||
	write_unlock_irq(&tasklist_lock);
 | 
						write_unlock_irq(&tasklist_lock);
 | 
				
			||||||
	rcu_read_unlock();
 | 
						rcu_read_unlock();
 | 
				
			||||||
	if (oldwork) {
 | 
						if (oldwork) {
 | 
				
			||||||
		put_cred(oldwork->data);
 | 
							put_cred(container_of(oldwork, struct kludge, twork)->cred);
 | 
				
			||||||
		kfree(oldwork);
 | 
							kfree(oldwork);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (newwork) {
 | 
						if (newwork) {
 | 
				
			||||||
		put_cred(newwork->data);
 | 
							put_cred(newwork->cred);
 | 
				
			||||||
		kfree(newwork);
 | 
							kfree(newwork);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return ret;
 | 
						return ret;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -837,9 +837,10 @@ long join_session_keyring(const char *name)
 | 
				
			||||||
void key_change_session_keyring(struct task_work *twork)
 | 
					void key_change_session_keyring(struct task_work *twork)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	const struct cred *old = current_cred();
 | 
						const struct cred *old = current_cred();
 | 
				
			||||||
	struct cred *new = twork->data;
 | 
						struct kludge *p = container_of(twork, struct kludge, twork);
 | 
				
			||||||
 | 
						struct cred *new = p->cred;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	kfree(twork);
 | 
						kfree(p);
 | 
				
			||||||
	if (unlikely(current->flags & PF_EXITING)) {
 | 
						if (unlikely(current->flags & PF_EXITING)) {
 | 
				
			||||||
		put_cred(new);
 | 
							put_cred(new);
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue