Skip to content

Commit

Permalink
lfq: bug fix -- only use copy_to/from_user when the reader/writer is …
Browse files Browse the repository at this point in the history
…userspace, otherwise use memcpy
  • Loading branch information
fcangialosi committed Jun 13, 2018
1 parent 57d94b5 commit b6716ba
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 23 deletions.
20 changes: 10 additions & 10 deletions ccpkp/ccpkp.c
Original file line number Diff line number Diff line change
Expand Up @@ -193,8 +193,8 @@ ssize_t ccpkp_user_read(struct file *fp, char *buf, size_t bytes_to_read, loff_t
#else
struct lfq *q = &(pipe->dp_write_queue);
#endif
//PDEBUG("user wants to read %lu bytes", bytes_to_read);
return lfq_read(q, buf, bytes_to_read);
PDEBUG("user wants to read %lu bytes", bytes_to_read);
return lfq_read(q, buf, bytes_to_read, USERSPACE);
}

// module stores pointer to corresponding ccp kpipe for each socket
Expand All @@ -204,15 +204,15 @@ ssize_t ccpkp_kernel_read(struct kpipe *pipe, char *buf, size_t bytes_to_read) {
return 0;
#endif
struct lfq *q = &(pipe->ccp_write_queue);
//DEBUG("kernel wants to read %lu bytes", bytes_to_read);
return lfq_read(q, buf, bytes_to_read);
PDEBUG("kernel wants to read %lu bytes", bytes_to_read);
return lfq_read(q, buf, bytes_to_read, KERNELSPACE);
}

ssize_t ccpkp_user_write(struct file *fp, const char *buf, size_t bytes_to_write, loff_t *offset) {
struct kpipe *pipe = fp->private_data;
struct lfq *q = &(pipe->ccp_write_queue);
//PDEBUG("user wants to write %lu bytes", bytes_to_write);
return lfq_write(q, buf, bytes_to_write, 0);
PDEBUG("user wants to write %lu bytes", bytes_to_write);
return lfq_write(q, buf, bytes_to_write, 0, USERSPACE);
}


Expand All @@ -223,8 +223,8 @@ ssize_t ccpkp_kernel_write(struct kpipe *pipe, const char *buf, size_t bytes_to_
return 0;
#endif
struct lfq *q = &(pipe->dp_write_queue);
//PDEBUG("kernel wants to write %lu bytes", bytes_to_write);
return lfq_write(q, buf, bytes_to_write, id);
PDEBUG("kernel wants to write %lu bytes", bytes_to_write);
return lfq_write(q, buf, bytes_to_write, id, KERNELSPACE);
}


Expand All @@ -233,7 +233,7 @@ void ccpkp_try_read(void) {
ssize_t bytes_read;
bytes_read = ccpkp_kernel_read(ccpkp_dev->pipes[curr_ccp_id], recvbuf, RECVBUF_LEN);
if (bytes_read > 0) {
PDEBUG("Kernel read %ld bytes", bytes_read);
PDEBUG("kernel read %ld bytes", bytes_read);
libccp_read_msg(recvbuf, bytes_read);
}
}
Expand All @@ -247,6 +247,6 @@ int ccpkp_sendmsg(
if (bytes_to_write < 0) {
return -1;
}
PDEBUG("CCP trying to write %d bytes", bytes_to_write);
PDEBUG("kernel->user trying to write %d bytes", bytes_to_write);
return ccpkp_kernel_write(ccpkp_dev->pipes[curr_ccp_id], buf, (size_t) bytes_to_write, (int) conn->index+1);
}
48 changes: 38 additions & 10 deletions ccpkp/lfq/lfq.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,25 @@
#include "lfq.h"

void debug_buf(const char *buf) {
char out[256];
char *tmp = out;
int wrote = sprintf(tmp, "buf=%p\n", buf);
tmp += wrote;
for(int i=0; i<64; i++) {
sprintf(tmp, "|%2d", i);
tmp += 3;
}
sprintf(tmp, "|\n");
printk( KERN_DEBUG "%s", out);
tmp = out;
for(int i=0; i<64; i++) {
sprintf(tmp, "|%02x", buf[i]);
tmp += 3;
}
sprintf(tmp, "|\n");
printk( KERN_DEBUG "%s", out);
}

int init_lfq(struct lfq *q, bool blocking) {
q->buf = __MALLOC__(BUF_LEN);
if (!q->buf) {
Expand Down Expand Up @@ -105,7 +125,7 @@ inline bool ready_for_reading(struct lfq *q) {
return (q->read_head != q->write_head) && (q->msg_list[q->read_head] != NULL);
}

ssize_t lfq_read(struct lfq *q, char *buf, size_t bytes_to_read) {
ssize_t lfq_read(struct lfq *q, char *buf, size_t bytes_to_read, int reader_t) {

if (q->blocking) {
wait_until_nonempty:
Expand Down Expand Up @@ -166,8 +186,12 @@ ssize_t lfq_read(struct lfq *q, char *buf, size_t bytes_to_read) {
int r = i % BACKLOG;
char *block = q->msg_list[r];
uint16_t bytes_in_block = read_portus_msg_size(block);
PDEBUG("[reader ] read #%d (@%ld) : %s\n", r, block-q->buf, block+4);
COPY_TO_USER(buf, block, bytes_in_block);
PDEBUG("[reader ] read #%d (@%ld) : %d bytes\n", r, block-q->buf, bytes_in_block);
if (reader_t == USERSPACE) {
COPY_TO_USER(buf, block, bytes_in_block);
} else { // reader_t == KERNELSPACE
memcpy(buf, block, bytes_in_block);
}
bytes_read += bytes_in_block;
_lfq_return_block(q, block);
q->msg_list[r] = NULL;
Expand All @@ -182,7 +206,7 @@ ssize_t lfq_read(struct lfq *q, char *buf, size_t bytes_to_read) {
}


ssize_t lfq_write(struct lfq *q, const char *buf, size_t bytes_to_write, int id) {
ssize_t lfq_write(struct lfq *q, const char *buf, size_t bytes_to_write, int id, int writer_t) {
// Get free block
char *block = _lfq_acquire_free_block(q);
if (block == NULL) {
Expand All @@ -192,7 +216,11 @@ ssize_t lfq_write(struct lfq *q, const char *buf, size_t bytes_to_write, int id)
PDEBUG("[writer %d] acquired free block at %ld (head=%d, tail=%d)\n", id, block - q->buf, q->free_head, q->free_tail);

// Copy data into block
COPY_FROM_USER(block, buf, bytes_to_write);
if (writer_t == USERSPACE) {
COPY_FROM_USER(block, buf, bytes_to_write);
} else { // writer_t == KERNELSPACE
memcpy(block, buf, bytes_to_write);
}

// Get next position in queue
idx_t old_i, new_i;
Expand All @@ -212,7 +240,7 @@ ssize_t lfq_write(struct lfq *q, const char *buf, size_t bytes_to_write, int id)
if (new_i == 0) {
new_i = BACKLOG;
}
PDEBUG("[writer %d] secured queue #%d : %s\n", id, (new_i-1), buf+4);
PDEBUG("[writer %d] secured queue #%d : %ld bytes\n", id, (new_i-1), bytes_to_write);

// Assign block to acquired position
q->msg_list[new_i-1] = block;
Expand All @@ -231,14 +259,14 @@ ssize_t lfq_write(struct lfq *q, const char *buf, size_t bytes_to_write, int id)
}

ssize_t ccp_write(struct pipe *p, const char *buf, size_t bytes_to_write, int id) {
return lfq_write(&p->ccp_write_queue, buf, bytes_to_write, id);
return lfq_write(&p->ccp_write_queue, buf, bytes_to_write, id, USERSPACE);
}
ssize_t ccp_read(struct pipe *p, char *buf, size_t bytes_to_read) {
return lfq_read(&p->dp_write_queue, buf, bytes_to_read);
return lfq_read(&p->dp_write_queue, buf, bytes_to_read, USERSPACE);
}
ssize_t dp_write(struct pipe *p, const char *buf, size_t bytes_to_write, int id) {
return lfq_write(&p->dp_write_queue, buf, bytes_to_write, id);
return lfq_write(&p->dp_write_queue, buf, bytes_to_write, id, KERNELSPACE);
}
ssize_t dp_read(struct pipe *p, char *buf, size_t bytes_to_read) {
return lfq_read(&p->ccp_write_queue, buf, bytes_to_read);
return lfq_read(&p->ccp_write_queue, buf, bytes_to_read, KERNELSPACE);
}
7 changes: 4 additions & 3 deletions ccpkp/lfq/lfq.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@
#endif

#define idx_t uint16_t

#define KERNELSPACE 0
#define USERSPACE 1

// Must be a divisor of max val of id_t
#define BACKLOG 1024
Expand Down Expand Up @@ -111,8 +112,8 @@ char* _lfq_acquire_free_block(struct lfq *q);
void _lfq_return_block(struct lfq *q, char *block);
uint16_t read_portus_msg_size(char *buf);

ssize_t lfq_read(struct lfq *q, char *buf, size_t bytes_to_read);
ssize_t lfq_write(struct lfq *q, const char *buf, size_t bytes_to_write, int id);
ssize_t lfq_read(struct lfq *q, char *buf, size_t bytes_to_read, int reader_t);
ssize_t lfq_write(struct lfq *q, const char *buf, size_t bytes_to_write, int id, int writer_t);
ssize_t ccp_write(struct pipe *p, const char *buf, size_t bytes_to_write, int id);
ssize_t ccp_read(struct pipe *p, char *buf, size_t bytes_to_read);
ssize_t dp_write(struct pipe *p, const char *buf, size_t bytes_to_write, int id);
Expand Down

0 comments on commit b6716ba

Please sign in to comment.