inline uint32_t EventRingBuffer<Time>::write(Time time, EventType type, uint32_t size, const uint8_t* buf) { if (write_space() < (sizeof(Time) + sizeof(EventType) + sizeof(uint32_t) + size)) { return 0; } else { PBD::RingBufferNPT<uint8_t>::write ((uint8_t*)&time, sizeof(Time)); PBD::RingBufferNPT<uint8_t>::write ((uint8_t*)&type, sizeof(EventType)); PBD::RingBufferNPT<uint8_t>::write ((uint8_t*)&size, sizeof(uint32_t)); PBD::RingBufferNPT<uint8_t>::write (buf, size); return size; } }
/* elf ----------------------------------------------------------------------*/ void elf(int fd_s, int fd_d, Elf32_Word p_type, Elf32_Word p_flags, Elf32_Addr* addr, int* size, int flag) { int i; Elf32_Ehdr e_eh; static Elf32_Phdr e_ph[32]; lseek(fd_s, 0, SEEK_SET); /* rewind */ readn(fd_s, &e_eh, sizeof(Elf32_Ehdr)); lseek(fd_s, e_eh.e_phoff, SEEK_SET); readn(fd_s, (char*)e_ph, e_eh.e_phentsize * e_eh.e_phnum); printf("#-----------------------------------------------------------------#\n"); printf("# [t]ype, [f]lag, [v]addr, [m]emsz, [s]filesz, [o]ffset #\n"); printf("# e_eh.e_phnum = %d\n", e_eh.e_phnum); for (i = 0 ; i < e_eh.e_phnum ; i ++) { printf("# ph[%d]: t = 0x%x, f = 0x%x, v = 0x%x, m = 0x%x, s = 0x%x o = %d\n", i, e_ph[i].p_type, e_ph[i].p_flags, e_ph[i].p_vaddr, e_ph[i].p_memsz, e_ph[i].p_filesz, e_ph[i].p_offset); if (e_ph[i].p_type == p_type && e_ph[i].p_flags == p_flags) { /* do everything ------------------------------------*/ if (flag) { write_space(fd_d, (int)(e_ph[i].p_vaddr - *addr) - *size); } lseek(fd_s, e_ph[i].p_offset, SEEK_SET); readn(fd_s, buf, e_ph[i].p_filesz); writen(fd_d, buf, e_ph[i].p_filesz); *addr = e_ph[i].p_vaddr; *size = e_ph[i].p_memsz; printf("# virtual address = 0x%x, size = 0x%x\n", *addr, *size); break; } } }
/* the core send_sem serializes this with other xmit and shutdown */ static int rds_tcp_sendmsg(struct socket *sock, void *data, unsigned int len) { struct kvec vec = { .iov_base = data, .iov_len = len, }; struct msghdr msg = { .msg_flags = MSG_DONTWAIT | MSG_NOSIGNAL, }; return kernel_sendmsg(sock, &msg, &vec, 1, vec.iov_len); } /* the core send_sem serializes this with other xmit and shutdown */ int rds_tcp_xmit(struct rds_connection *conn, struct rds_message *rm, unsigned int hdr_off, unsigned int sg, unsigned int off) { struct rds_conn_path *cp = rm->m_inc.i_conn_path; struct rds_tcp_connection *tc = cp->cp_transport_data; int done = 0; int ret = 0; int more; if (hdr_off == 0) { /* * m_ack_seq is set to the sequence number of the last byte of * header and data. see rds_tcp_is_acked(). */ tc->t_last_sent_nxt = rds_tcp_snd_nxt(tc); rm->m_ack_seq = tc->t_last_sent_nxt + sizeof(struct rds_header) + be32_to_cpu(rm->m_inc.i_hdr.h_len) - 1; smp_mb__before_atomic(); set_bit(RDS_MSG_HAS_ACK_SEQ, &rm->m_flags); tc->t_last_expected_una = rm->m_ack_seq + 1; if (test_bit(RDS_MSG_RETRANSMITTED, &rm->m_flags)) rm->m_inc.i_hdr.h_flags |= RDS_FLAG_RETRANSMITTED; rdsdebug("rm %p tcp nxt %u ack_seq %llu\n", rm, rds_tcp_snd_nxt(tc), (unsigned long long)rm->m_ack_seq); } if (hdr_off < sizeof(struct rds_header)) { /* see rds_tcp_write_space() */ set_bit(SOCK_NOSPACE, &tc->t_sock->sk->sk_socket->flags); ret = rds_tcp_sendmsg(tc->t_sock, (void *)&rm->m_inc.i_hdr + hdr_off, sizeof(rm->m_inc.i_hdr) - hdr_off); if (ret < 0) goto out; done += ret; if (hdr_off + done != sizeof(struct rds_header)) goto out; } more = rm->data.op_nents > 1 ? (MSG_MORE | MSG_SENDPAGE_NOTLAST) : 0; while (sg < rm->data.op_nents) { int flags = MSG_DONTWAIT | MSG_NOSIGNAL | more; ret = tc->t_sock->ops->sendpage(tc->t_sock, sg_page(&rm->data.op_sg[sg]), rm->data.op_sg[sg].offset + off, rm->data.op_sg[sg].length - off, flags); rdsdebug("tcp sendpage %p:%u:%u ret %d\n", (void *)sg_page(&rm->data.op_sg[sg]), rm->data.op_sg[sg].offset + off, rm->data.op_sg[sg].length - off, ret); if (ret <= 0) break; off += ret; done += ret; if (off == rm->data.op_sg[sg].length) { off = 0; sg++; } if (sg == rm->data.op_nents - 1) more = 0; } out: if (ret <= 0) { /* write_space will hit after EAGAIN, all else fatal */ if (ret == -EAGAIN) { rds_tcp_stats_inc(s_tcp_sndbuf_full); ret = 0; } else { /* No need to disconnect/reconnect if path_drop * has already been triggered, because, e.g., of * an incoming RST. */ if (rds_conn_path_up(cp)) { pr_warn("RDS/tcp: send to %pI4 on cp [%d]" "returned %d, " "disconnecting and reconnecting\n", &conn->c_faddr, cp->cp_index, ret); rds_conn_path_drop(cp); } } } if (done == 0) done = ret; return done; } /* * rm->m_ack_seq is set to the tcp sequence number that corresponds to the * last byte of the message, including the header. This means that the * entire message has been received if rm->m_ack_seq is "before" the next * unacked byte of the TCP sequence space. We have to do very careful * wrapping 32bit comparisons here. */ static int rds_tcp_is_acked(struct rds_message *rm, uint64_t ack) { if (!test_bit(RDS_MSG_HAS_ACK_SEQ, &rm->m_flags)) return 0; return (__s32)((u32)rm->m_ack_seq - (u32)ack) < 0; } void rds_tcp_write_space(struct sock *sk) { void (*write_space)(struct sock *sk); struct rds_conn_path *cp; struct rds_tcp_connection *tc; read_lock_bh(&sk->sk_callback_lock); cp = sk->sk_user_data; if (!cp) { write_space = sk->sk_write_space; goto out; } tc = cp->cp_transport_data; rdsdebug("write_space for tc %p\n", tc); write_space = tc->t_orig_write_space; rds_tcp_stats_inc(s_tcp_write_space_calls); rdsdebug("tcp una %u\n", rds_tcp_snd_una(tc)); tc->t_last_seen_una = rds_tcp_snd_una(tc); rds_send_path_drop_acked(cp, rds_tcp_snd_una(tc), rds_tcp_is_acked); if ((atomic_read(&sk->sk_wmem_alloc) << 1) <= sk->sk_sndbuf) queue_delayed_work(rds_wq, &cp->cp_send_w, 0); out: read_unlock_bh(&sk->sk_callback_lock); /* * write_space is only called when data leaves tcp's send queue if * SOCK_NOSPACE is set. We set SOCK_NOSPACE every time we put * data in tcp's send queue because we use write_space to parse the * sequence numbers and notice that rds messages have been fully * received. * * tcp's write_space clears SOCK_NOSPACE if the send queue has more * than a certain amount of space. So we need to set it again *after* * we call tcp's write_space or else we might only get called on the * first of a series of incoming tcp acks. */ write_space(sk); if (sk->sk_socket) set_bit(SOCK_NOSPACE, &sk->sk_socket->flags); }
/* the core send_sem serializes this with other xmit and shutdown */ int rds_tcp_sendmsg(struct socket *sock, void *data, unsigned int len) { struct kvec vec = { .iov_base = data, .iov_len = len, }; struct msghdr msg = { .msg_flags = MSG_DONTWAIT | MSG_NOSIGNAL, }; return kernel_sendmsg(sock, &msg, &vec, 1, vec.iov_len); } /* the core send_sem serializes this with other xmit and shutdown */ int rds_tcp_xmit_cong_map(struct rds_connection *conn, struct rds_cong_map *map, unsigned long offset) { static struct rds_header rds_tcp_map_header = { .h_flags = RDS_FLAG_CONG_BITMAP, }; struct rds_tcp_connection *tc = conn->c_transport_data; unsigned long i; int ret; int copied = 0; /* Some problem claims cpu_to_be32(constant) isn't a constant. */ rds_tcp_map_header.h_len = cpu_to_be32(RDS_CONG_MAP_BYTES); if (offset < sizeof(struct rds_header)) { ret = rds_tcp_sendmsg(tc->t_sock, (void *)&rds_tcp_map_header + offset, sizeof(struct rds_header) - offset); if (ret <= 0) return ret; offset += ret; copied = ret; if (offset < sizeof(struct rds_header)) return ret; } offset -= sizeof(struct rds_header); i = offset / PAGE_SIZE; offset = offset % PAGE_SIZE; BUG_ON(i >= RDS_CONG_MAP_PAGES); do { ret = tc->t_sock->ops->sendpage(tc->t_sock, virt_to_page(map->m_page_addrs[i]), offset, PAGE_SIZE - offset, MSG_DONTWAIT); if (ret <= 0) break; copied += ret; offset += ret; if (offset == PAGE_SIZE) { offset = 0; i++; } } while (i < RDS_CONG_MAP_PAGES); return copied ? copied : ret; } /* the core send_sem serializes this with other xmit and shutdown */ int rds_tcp_xmit(struct rds_connection *conn, struct rds_message *rm, unsigned int hdr_off, unsigned int sg, unsigned int off) { struct rds_tcp_connection *tc = conn->c_transport_data; int done = 0; int ret = 0; if (hdr_off == 0) { /* * m_ack_seq is set to the sequence number of the last byte of * header and data. see rds_tcp_is_acked(). */ tc->t_last_sent_nxt = rds_tcp_snd_nxt(tc); rm->m_ack_seq = tc->t_last_sent_nxt + sizeof(struct rds_header) + be32_to_cpu(rm->m_inc.i_hdr.h_len) - 1; smp_mb__before_clear_bit(); set_bit(RDS_MSG_HAS_ACK_SEQ, &rm->m_flags); tc->t_last_expected_una = rm->m_ack_seq + 1; rdsdebug("rm %p tcp nxt %u ack_seq %llu\n", rm, rds_tcp_snd_nxt(tc), (unsigned long long)rm->m_ack_seq); } if (hdr_off < sizeof(struct rds_header)) { /* see rds_tcp_write_space() */ set_bit(SOCK_NOSPACE, &tc->t_sock->sk->sk_socket->flags); ret = rds_tcp_sendmsg(tc->t_sock, (void *)&rm->m_inc.i_hdr + hdr_off, sizeof(rm->m_inc.i_hdr) - hdr_off); if (ret < 0) goto out; done += ret; if (hdr_off + done != sizeof(struct rds_header)) goto out; } while (sg < rm->m_nents) { ret = tc->t_sock->ops->sendpage(tc->t_sock, sg_page(&rm->m_sg[sg]), rm->m_sg[sg].offset + off, rm->m_sg[sg].length - off, MSG_DONTWAIT|MSG_NOSIGNAL); rdsdebug("tcp sendpage %p:%u:%u ret %d\n", (void *)sg_page(&rm->m_sg[sg]), rm->m_sg[sg].offset + off, rm->m_sg[sg].length - off, ret); if (ret <= 0) break; off += ret; done += ret; if (off == rm->m_sg[sg].length) { off = 0; sg++; } } out: if (ret <= 0) { /* write_space will hit after EAGAIN, all else fatal */ if (ret == -EAGAIN) { rds_tcp_stats_inc(s_tcp_sndbuf_full); ret = 0; } else { printk(KERN_WARNING "RDS/tcp: send to %pI4 " "returned %d, disconnecting and reconnecting\n", &conn->c_faddr, ret); rds_conn_drop(conn); } } if (done == 0) done = ret; return done; } /* * rm->m_ack_seq is set to the tcp sequence number that corresponds to the * last byte of the message, including the header. This means that the * entire message has been received if rm->m_ack_seq is "before" the next * unacked byte of the TCP sequence space. We have to do very careful * wrapping 32bit comparisons here. */ static int rds_tcp_is_acked(struct rds_message *rm, uint64_t ack) { if (!test_bit(RDS_MSG_HAS_ACK_SEQ, &rm->m_flags)) return 0; return (__s32)((u32)rm->m_ack_seq - (u32)ack) < 0; } void rds_tcp_write_space(struct sock *sk) { void (*write_space)(struct sock *sk); struct rds_connection *conn; struct rds_tcp_connection *tc; read_lock_bh(&sk->sk_callback_lock); conn = sk->sk_user_data; if (conn == NULL) { write_space = sk->sk_write_space; goto out; } tc = conn->c_transport_data; rdsdebug("write_space for tc %p\n", tc); write_space = tc->t_orig_write_space; rds_tcp_stats_inc(s_tcp_write_space_calls); rdsdebug("tcp una %u\n", rds_tcp_snd_una(tc)); tc->t_last_seen_una = rds_tcp_snd_una(tc); rds_send_drop_acked(conn, rds_tcp_snd_una(tc), rds_tcp_is_acked); if ((atomic_read(&sk->sk_wmem_alloc) << 1) <= sk->sk_sndbuf) queue_delayed_work(rds_wq, &conn->c_send_w, 0); out: read_unlock_bh(&sk->sk_callback_lock); /* * write_space is only called when data leaves tcp's send queue if * SOCK_NOSPACE is set. We set SOCK_NOSPACE every time we put * data in tcp's send queue because we use write_space to parse the * sequence numbers and notice that rds messages have been fully * received. * * tcp's write_space clears SOCK_NOSPACE if the send queue has more * than a certain amount of space. So we need to set it again *after* * we call tcp's write_space or else we might only get called on the * first of a series of incoming tcp acks. */ write_space(sk); if (sk->sk_socket) set_bit(SOCK_NOSPACE, &sk->sk_socket->flags); }
static int rds_tcp_sendmsg(struct socket *sock, void *data, unsigned int len) { struct kvec vec = { .iov_base = data, .iov_len = len, }; struct msghdr msg = { .msg_flags = MSG_DONTWAIT | MSG_NOSIGNAL, }; return kernel_sendmsg(sock, &msg, &vec, 1, vec.iov_len); } int rds_tcp_xmit(struct rds_connection *conn, struct rds_message *rm, unsigned int hdr_off, unsigned int sg, unsigned int off) { struct rds_tcp_connection *tc = conn->c_transport_data; int done = 0; int ret = 0; if (hdr_off == 0) { tc->t_last_sent_nxt = rds_tcp_snd_nxt(tc); rm->m_ack_seq = tc->t_last_sent_nxt + sizeof(struct rds_header) + be32_to_cpu(rm->m_inc.i_hdr.h_len) - 1; smp_mb__before_clear_bit(); set_bit(RDS_MSG_HAS_ACK_SEQ, &rm->m_flags); tc->t_last_expected_una = rm->m_ack_seq + 1; rdsdebug("rm %p tcp nxt %u ack_seq %llu\n", rm, rds_tcp_snd_nxt(tc), (unsigned long long)rm->m_ack_seq); } if (hdr_off < sizeof(struct rds_header)) { set_bit(SOCK_NOSPACE, &tc->t_sock->sk->sk_socket->flags); ret = rds_tcp_sendmsg(tc->t_sock, (void *)&rm->m_inc.i_hdr + hdr_off, sizeof(rm->m_inc.i_hdr) - hdr_off); if (ret < 0) goto out; done += ret; if (hdr_off + done != sizeof(struct rds_header)) goto out; } while (sg < rm->data.op_nents) { ret = tc->t_sock->ops->sendpage(tc->t_sock, sg_page(&rm->data.op_sg[sg]), rm->data.op_sg[sg].offset + off, rm->data.op_sg[sg].length - off, MSG_DONTWAIT|MSG_NOSIGNAL); rdsdebug("tcp sendpage %p:%u:%u ret %d\n", (void *)sg_page(&rm->data.op_sg[sg]), rm->data.op_sg[sg].offset + off, rm->data.op_sg[sg].length - off, ret); if (ret <= 0) break; off += ret; done += ret; if (off == rm->data.op_sg[sg].length) { off = 0; sg++; } } out: if (ret <= 0) { if (ret == -EAGAIN) { rds_tcp_stats_inc(s_tcp_sndbuf_full); ret = 0; } else { printk(KERN_WARNING "RDS/tcp: send to %pI4 " "returned %d, disconnecting and reconnecting\n", &conn->c_faddr, ret); rds_conn_drop(conn); } } if (done == 0) done = ret; return done; } static int rds_tcp_is_acked(struct rds_message *rm, uint64_t ack) { if (!test_bit(RDS_MSG_HAS_ACK_SEQ, &rm->m_flags)) return 0; return (__s32)((u32)rm->m_ack_seq - (u32)ack) < 0; } void rds_tcp_write_space(struct sock *sk) { void (*write_space)(struct sock *sk); struct rds_connection *conn; struct rds_tcp_connection *tc; read_lock_bh(&sk->sk_callback_lock); conn = sk->sk_user_data; if (!conn) { write_space = sk->sk_write_space; goto out; } tc = conn->c_transport_data; rdsdebug("write_space for tc %p\n", tc); write_space = tc->t_orig_write_space; rds_tcp_stats_inc(s_tcp_write_space_calls); rdsdebug("tcp una %u\n", rds_tcp_snd_una(tc)); tc->t_last_seen_una = rds_tcp_snd_una(tc); rds_send_drop_acked(conn, rds_tcp_snd_una(tc), rds_tcp_is_acked); if ((atomic_read(&sk->sk_wmem_alloc) << 1) <= sk->sk_sndbuf) queue_delayed_work(rds_wq, &conn->c_send_w, 0); out: read_unlock_bh(&sk->sk_callback_lock); write_space(sk); if (sk->sk_socket) set_bit(SOCK_NOSPACE, &sk->sk_socket->flags); }