*/
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/mutex.h>
#include <linux/slab.h>
#include <linux/kthread.h>
#include <linux/delay.h>
u8 version_major;
u8 version_minor;
+ struct mutex mutex;
struct task_struct *task;
wait_queue_head_t wq;
struct gb_connection *connection = to_gb_connection(dev); \
struct gb_loopback *gb = \
(struct gb_loopback *)connection->private; \
+ mutex_lock(&gb->mutex); \
ret = sscanf(buf, "%"#type, &gb->field); \
if (ret != 1) \
- return -EINVAL; \
- gb_loopback_check_attr(gb); \
+ len = -EINVAL; \
+ else \
+ gb_loopback_check_attr(gb); \
+ mutex_unlock(&gb->mutex); \
return len; \
} \
static DEVICE_ATTR_RW(field)
static int gb_loopback_fn(void *data)
{
int error = 0;
+ int ms_wait;
struct gb_loopback *gb = (struct gb_loopback *)data;
while (1) {
kthread_should_stop());
if (kthread_should_stop())
break;
+
+ mutex_lock(&gb->mutex);
if (gb->iteration_max) {
if (gb->iteration_count < gb->iteration_max) {
gb->iteration_count++;
"iteration_count");
} else {
gb->type = 0;
+ mutex_unlock(&gb->mutex);
continue;
}
}
if (error)
gb->error++;
gb_loopback_calculate_stats(gb);
- if (gb->ms_wait)
- msleep(gb->ms_wait);
+ ms_wait = gb->ms_wait;
+ mutex_unlock(&gb->mutex);
+ if (ms_wait)
+ msleep(ms_wait);
}
return 0;
}
gb_loopback_reset_stats(gb);
init_waitqueue_head(&gb->wq);
+ mutex_init(&gb->mutex);
gb->task = kthread_run(gb_loopback_fn, gb, "gb_loopback");
if (IS_ERR(gb->task)) {
retval = PTR_ERR(gb->task);