⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wthread.c

📁 iscsi企业级target.很好用
💻 C
字号:
/* * Worker thread. * (C) 2004 - 2005 FUJITA Tomonori <tomof@acm.org> * This code is licenced under the GPL. */#include <linux/kthread.h>#include "iscsi.h"#include "iscsi_dbg.h"void wthread_queue(struct iscsi_cmnd *cmnd){	struct worker_thread_info *info = &cmnd->conn->session->target->wthread_info;	if (!list_empty(&cmnd->list)) {		struct iscsi_scsi_cmd_hdr *req = cmnd_hdr(cmnd);		eprintk("%x %p %x %x %x %x %lx %x\n",			cmnd_itt(cmnd), req, req->opcode, req->scb[0], cmnd->pdu.datasize,			be32_to_cpu(req->data_length), cmnd->flags, req->flags);		if (cmnd->lun)			eprintk("%u\n", cmnd->lun->lun);		assert(list_empty(&cmnd->list));	}	spin_lock(&info->wthread_lock);	list_add_tail(&cmnd->list, &info->work_queue);	spin_unlock(&info->wthread_lock);	wake_up(&info->wthread_sleep);}static struct iscsi_cmnd * get_ready_cmnd(struct worker_thread_info *info){	struct iscsi_cmnd *cmnd = NULL;	spin_lock(&info->wthread_lock);	if (!list_empty(&info->work_queue)) {		cmnd = list_entry(info->work_queue.next, struct iscsi_cmnd, list);		list_del_init(&cmnd->list);		assert(cmnd->conn);		atomic_inc(&cmnd->conn->nr_busy_cmnds);	}	spin_unlock(&info->wthread_lock);	return cmnd;}static int cmnd_execute(struct iscsi_cmnd *cmnd){	int type = cmnd->conn->session->target->trgt_param.target_type;	assert(target_type_array[type]->execute_cmnd);	return target_type_array[type]->execute_cmnd(cmnd);}static int worker_thread(void *arg){	struct worker_thread *wt = (struct worker_thread *) arg;	struct worker_thread_info *info = wt->w_info;	struct iscsi_cmnd *cmnd;	struct iscsi_conn *conn;	DECLARE_WAITQUEUE(wait, current);	add_wait_queue(&info->wthread_sleep, &wait);	__set_current_state(TASK_RUNNING);	do {		while (!list_empty(&info->work_queue) &&		       (cmnd = get_ready_cmnd(info))) {			conn = cmnd->conn;			cmnd_execute(cmnd);			assert(conn);			atomic_dec(&conn->nr_busy_cmnds);		}		__set_current_state(TASK_INTERRUPTIBLE);		if (list_empty(&info->work_queue))			schedule();		__set_current_state(TASK_RUNNING);	} while (!kthread_should_stop());	remove_wait_queue(&info->wthread_sleep, &wait);	return 0;}static int start_one_worker_thread(struct iscsi_target *target){	struct worker_thread_info *info = &target->wthread_info;	struct worker_thread *wt;	struct task_struct *task;	if (!(wt = kmalloc(sizeof(struct worker_thread), GFP_KERNEL)))		return -ENOMEM;	wt->w_info = info;	task = kthread_create(worker_thread, wt, "istiod%d", target->tid);	if (IS_ERR(task)) {		kfree(wt);		return PTR_ERR(task);	}	wt->w_task = task;	list_add(&wt->w_list, &info->wthread_list);	info->nr_running_wthreads++;	wake_up_process(task);	return 0;}static int stop_one_worker_thread(struct worker_thread *wt){	struct worker_thread_info *info = wt->w_info;	int err;	assert(wt->w_task);	if ((err = kthread_stop(wt->w_task)) < 0)		return err;	list_del(&wt->w_list);	kfree(wt);	info->nr_running_wthreads--;	return 0;}int wthread_init(struct iscsi_target *target){	struct worker_thread_info *info = &target->wthread_info;	spin_lock_init(&info->wthread_lock);	info->nr_running_wthreads = 0;	INIT_LIST_HEAD(&info->work_queue);	INIT_LIST_HEAD(&info->wthread_list);	init_waitqueue_head(&info->wthread_sleep);	return 0;}int wthread_start(struct iscsi_target *target){	int err = 0;	struct worker_thread_info *info = &target->wthread_info;	while (info->nr_running_wthreads < target->trgt_param.wthreads) {		if ((err = start_one_worker_thread(target)) < 0) {			eprintk("Fail to create a worker thread %d\n", err);			goto out;		}	}	while (info->nr_running_wthreads > target->trgt_param.wthreads) {		struct worker_thread *wt;		wt = list_entry(info->wthread_list.next, struct worker_thread, w_list);		if ((err = stop_one_worker_thread(wt)) < 0) {			eprintk("Fail to stop a worker thread %d\n", err);			break;		}	}out:	return err;}int wthread_stop(struct iscsi_target *target){	struct worker_thread *wt, *tmp;	int err = 0;	struct worker_thread_info *info = &target->wthread_info;	list_for_each_entry_safe(wt, tmp, &info->wthread_list, w_list) {		if ((err = stop_one_worker_thread(wt)) < 0) {			eprintk("Fail to stop a worker thread %d\n", err);			return err;		}	}	return err;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -