diff --git a/homa.h b/homa.h index e7c35d4..218a101 100644 --- a/homa.h +++ b/homa.h @@ -127,7 +127,7 @@ struct homa_recvmsg_args { */ uint32_t num_bpages; - /* Reserved for future use; must be zero. */ + /* Reserved for future use; must be zero. */ uint32_t _pad[1]; /** diff --git a/homa_grant.c b/homa_grant.c index e799579..3bb5571 100644 --- a/homa_grant.c +++ b/homa_grant.c @@ -148,6 +148,7 @@ void homa_grant_add_rpc(struct homa_rpc *rpc) list_add(&prev_peer->grantable_links, &peer->grantable_links); } done: + return; } /** @@ -270,6 +271,7 @@ int homa_grant_send(struct homa_rpc *rpc, struct homa *homa) * WILL RELEASE THE LOCK before returning. */ void homa_grant_check_rpc(struct homa_rpc *rpc) + __releases(rpc->bucket_lock) { /* Overall design notes: * The grantable lock has proven to be a performance bottleneck, @@ -605,6 +607,7 @@ void homa_grant_find_oldest(struct homa *homa) * @rpc: The RPC to clean up. Must be locked by the caller. */ void homa_grant_free_rpc(struct homa_rpc *rpc) + __releases(rpc->bucket_lock) { struct homa *homa = rpc->hsk->homa; @@ -645,6 +648,7 @@ void homa_grant_free_rpc(struct homa_rpc *rpc) * thread started a fresh calculation after this method was invoked. */ int homa_grantable_lock_slow(struct homa *homa, int recalc) + __acquires(&homa->grantable_lock) { int starting_count = atomic_read(&homa->grant_recalc_count); __u64 start = sched_clock(); diff --git a/homa_grant.h b/homa_grant.h index 68feca1..45073e6 100644 --- a/homa_grant.h +++ b/homa_grant.h @@ -5,22 +5,22 @@ #ifndef _HOMA_GRANT_H #define _HOMA_GRANT_H -extern int homa_grantable_lock_slow(struct homa *homa, int recalc); -extern void homa_grant_add_rpc(struct homa_rpc *rpc); -extern void homa_grant_check_rpc(struct homa_rpc *rpc); -extern void homa_grant_find_oldest(struct homa *homa); -extern void homa_grant_free_rpc(struct homa_rpc *rpc); -extern void homa_grant_log_tt(struct homa *homa); -extern int homa_grant_outranks(struct homa_rpc *rpc1, - struct homa_rpc *rpc2); -extern int homa_grant_pick_rpcs(struct homa *homa, struct homa_rpc **rpcs, - int max_rpcs); -extern void homa_grant_pkt(struct sk_buff *skb, struct homa_rpc *rpc); -extern void homa_grant_recalc(struct homa *homa, int locked); -extern void homa_grant_remove_rpc(struct homa_rpc *rpc); -extern int homa_grant_send(struct homa_rpc *rpc, struct homa *homa); -extern int homa_grant_update_incoming(struct homa_rpc *rpc, - struct homa *homa); +int homa_grantable_lock_slow(struct homa *homa, int recalc); +void homa_grant_add_rpc(struct homa_rpc *rpc); +void homa_grant_check_rpc(struct homa_rpc *rpc); +void homa_grant_find_oldest(struct homa *homa); +void homa_grant_free_rpc(struct homa_rpc *rpc); +void homa_grant_log_tt(struct homa *homa); +int homa_grant_outranks(struct homa_rpc *rpc1, + struct homa_rpc *rpc2); +int homa_grant_pick_rpcs(struct homa *homa, struct homa_rpc **rpcs, + int max_rpcs); +void homa_grant_pkt(struct sk_buff *skb, struct homa_rpc *rpc); +void homa_grant_recalc(struct homa *homa, int locked); +void homa_grant_remove_rpc(struct homa_rpc *rpc); +int homa_grant_send(struct homa_rpc *rpc, struct homa *homa); +int homa_grant_update_incoming(struct homa_rpc *rpc, + struct homa *homa); /** * homa_grantable_lock() - Acquire the grantable lock. If the lock @@ -34,6 +34,7 @@ extern int homa_grant_update_incoming(struct homa_rpc *rpc, * thread started a fresh calculation after this method was invoked. */ static inline int homa_grantable_lock(struct homa *homa, int recalc) + __acquires(&homa->grantable_lock) { int result; @@ -50,10 +51,11 @@ static inline int homa_grantable_lock(struct homa *homa, int recalc) * @homa: Overall data about the Homa protocol implementation. */ static inline void homa_grantable_unlock(struct homa *homa) + __releases(&homa->grantable_lock) { INC_METRIC(grantable_lock_ns, sched_clock() - homa->grantable_lock_time); spin_unlock_bh(&homa->grantable_lock); } -#endif /* _HOMA_GRANT_H */ \ No newline at end of file +#endif /* _HOMA_GRANT_H */ diff --git a/homa_impl.h b/homa_impl.h index 92c8742..a3e0a2a 100644 --- a/homa_impl.h +++ b/homa_impl.h @@ -936,6 +936,7 @@ static inline void homa_set_doff(struct data_header *h, int size) * @homa: Overall data about the Homa protocol implementation. */ static inline void homa_throttle_lock(struct homa *homa) + __acquires(&homa->throttle_lock) { if (!spin_trylock_bh(&homa->throttle_lock)) homa_throttle_lock_slow(homa); @@ -946,6 +947,7 @@ static inline void homa_throttle_lock(struct homa *homa) * @homa: Overall data about the Homa protocol implementation. */ static inline void homa_throttle_unlock(struct homa *homa) + __releases(&homa->throttle_lock) { spin_unlock_bh(&homa->throttle_lock); } @@ -967,7 +969,7 @@ static inline struct in6_addr ipv4_to_ipv6(__be32 ip4) { struct in6_addr ret = {}; - if (ip4 == INADDR_ANY) + if (ip4 == htonl(INADDR_ANY)) return in6addr_any; ret.in6_u.u6_addr32[2] = htonl(0xffff); ret.in6_u.u6_addr32[3] = ip4; @@ -1040,7 +1042,7 @@ static inline bool is_homa_pkt(struct sk_buff *skb) * provide a unique identifier for the address in a timetrace record. * @x: Address (either IPv6 or IPv4-mapped IPv6) */ -static inline __be32 tt_addr(const struct in6_addr x) +static inline uint32_t tt_addr(const struct in6_addr x) { return is_mapped_ipv4(x) ? ntohl(x.in6_u.u6_addr32[3]) : (x.in6_u.u6_addr32[3] ? ntohl(x.in6_u.u6_addr32[3]) @@ -1060,132 +1062,129 @@ void unit_hook(char *id); #endif /* __UNIT_TEST__ */ #endif /* See strip.py */ -extern void homa_abort_rpcs(struct homa *homa, const struct in6_addr *addr, - int port, int error); -extern void homa_abort_sock_rpcs(struct homa_sock *hsk, int error); -extern void homa_ack_pkt(struct sk_buff *skb, struct homa_sock *hsk, - struct homa_rpc *rpc); -extern void homa_add_packet(struct homa_rpc *rpc, struct sk_buff *skb); -extern void homa_add_to_throttled(struct homa_rpc *rpc); -extern int homa_backlog_rcv(struct sock *sk, struct sk_buff *skb); -extern int homa_bind(struct socket *sk, struct sockaddr *addr, - int addr_len); -extern int homa_check_nic_queue(struct homa *homa, struct sk_buff *skb, - bool force); -extern struct homa_rpc - *homa_choose_fifo_grant(struct homa *homa); -extern struct homa_interest - *homa_choose_interest(struct homa *homa, struct list_head *head, - int offset); -extern void homa_close(struct sock *sock, long timeout); -extern int homa_copy_to_user(struct homa_rpc *rpc); -extern void homa_cutoffs_pkt(struct sk_buff *skb, struct homa_sock *hsk); -extern void homa_data_pkt(struct sk_buff *skb, struct homa_rpc *rpc); -extern void homa_destroy(struct homa *homa); -extern int homa_disconnect(struct sock *sk, int flags); -extern void homa_dispatch_pkts(struct sk_buff *skb, struct homa *homa); +void homa_abort_rpcs(struct homa *homa, const struct in6_addr *addr, + int port, int error); +void homa_abort_sock_rpcs(struct homa_sock *hsk, int error); +void homa_ack_pkt(struct sk_buff *skb, struct homa_sock *hsk, + struct homa_rpc *rpc); +void homa_add_packet(struct homa_rpc *rpc, struct sk_buff *skb); +void homa_add_to_throttled(struct homa_rpc *rpc); +int homa_backlog_rcv(struct sock *sk, struct sk_buff *skb); +int homa_bind(struct socket *sk, struct sockaddr *addr, + int addr_len); +int homa_check_nic_queue(struct homa *homa, struct sk_buff *skb, + bool force); +struct homa_rpc *homa_choose_fifo_grant(struct homa *homa); +struct homa_interest *homa_choose_interest(struct homa *homa, + struct list_head *head, + int offset); +void homa_close(struct sock *sock, long timeout); +int homa_copy_to_user(struct homa_rpc *rpc); +void homa_cutoffs_pkt(struct sk_buff *skb, struct homa_sock *hsk); +void homa_data_pkt(struct sk_buff *skb, struct homa_rpc *rpc); +void homa_destroy(struct homa *homa); +int homa_disconnect(struct sock *sk, int flags); +void homa_dispatch_pkts(struct sk_buff *skb, struct homa *homa); #if LINUX_VERSION_CODE < KERNEL_VERSION(6, 12, 0) -extern int homa_dointvec(struct ctl_table *table, int write, - void __user *buffer, size_t *lenp, loff_t *ppos); +int homa_dointvec(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos); #else -extern int homa_dointvec(const struct ctl_table *table, int write, - void __user *buffer, size_t *lenp, loff_t *ppos); +int homa_dointvec(const struct ctl_table *table, int write, + void *buffer, size_t *lenp, loff_t *ppos); #endif -extern int homa_err_handler_v4(struct sk_buff *skb, u32 info); -extern int homa_err_handler_v6(struct sk_buff *skb, - struct inet6_skb_parm *opt, u8 type, u8 code, int offset, - __be32 info); -extern int homa_fill_data_interleaved(struct homa_rpc *rpc, - struct sk_buff *skb, struct iov_iter *iter); -extern void homa_freeze(struct homa_rpc *rpc, enum homa_freeze_type type, - char *format); -extern void homa_freeze_peers(struct homa *homa); -extern struct homa_gap - *homa_gap_new(struct list_head *next, int start, int end); -extern void homa_gap_retry(struct homa_rpc *rpc); -extern int homa_get_port(struct sock *sk, unsigned short snum); -extern int homa_getsockopt(struct sock *sk, int level, int optname, - char __user *optval, int __user *option); -extern int homa_hash(struct sock *sk); -extern enum hrtimer_restart - homa_hrtimer(struct hrtimer *timer); -extern int homa_init(struct homa *homa); -extern void homa_incoming_sysctl_changed(struct homa *homa); -extern int homa_ioc_abort(struct sock *sk, int *karg); -extern int homa_ioctl(struct sock *sk, int cmd, int *karg); -extern void homa_log_throttled(struct homa *homa); -extern int homa_message_in_init(struct homa_rpc *rpc, int length, - int unsched); -extern int homa_message_out_fill(struct homa_rpc *rpc, - struct iov_iter *iter, int xmit); -extern void homa_message_out_init(struct homa_rpc *rpc, int length); -extern void homa_need_ack_pkt(struct sk_buff *skb, struct homa_sock *hsk, - struct homa_rpc *rpc); -extern struct sk_buff - *homa_new_data_packet(struct homa_rpc *rpc, - struct iov_iter *iter, int offset, int length, - int max_seg_data); -extern void homa_outgoing_sysctl_changed(struct homa *homa); -extern int homa_pacer_main(void *transportInfo); -extern void homa_pacer_stop(struct homa *homa); -extern void homa_pacer_xmit(struct homa *homa); -extern __poll_t homa_poll(struct file *file, struct socket *sock, - struct poll_table_struct *wait); -extern char *homa_print_ipv4_addr(__be32 addr); -extern char *homa_print_ipv6_addr(const struct in6_addr *addr); -extern char *homa_print_packet(struct sk_buff *skb, char *buffer, int buf_len); -extern char *homa_print_packet_short(struct sk_buff *skb, char *buffer, - int buf_len); -extern void homa_prios_changed(struct homa *homa); -extern int homa_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, - int flags, int *addr_len); -extern int homa_register_interests(struct homa_interest *interest, - struct homa_sock *hsk, int flags, __u64 id); -extern void homa_remove_from_throttled(struct homa_rpc *rpc); -extern void homa_resend_data(struct homa_rpc *rpc, int start, int end, - int priority); -extern void homa_resend_pkt(struct sk_buff *skb, struct homa_rpc *rpc, - struct homa_sock *hsk); -extern void homa_rpc_abort(struct homa_rpc *crpc, int error); -extern void homa_rpc_acked(struct homa_sock *hsk, - const struct in6_addr *saddr, struct homa_ack *ack); -extern void homa_rpc_free(struct homa_rpc *rpc); -extern void homa_rpc_handoff(struct homa_rpc *rpc); -extern int homa_sendmsg(struct sock *sk, struct msghdr *msg, size_t len); -extern int homa_setsockopt(struct sock *sk, int level, int optname, - sockptr_t __user optval, unsigned int optlen); -extern int homa_shutdown(struct socket *sock, int how); -extern int homa_snprintf(char *buffer, int size, int used, - const char *format, ...) __printf(4, 5); -extern int homa_softirq(struct sk_buff *skb); -extern void homa_spin(int ns); -extern char *homa_symbol_for_type(uint8_t type); +int homa_err_handler_v4(struct sk_buff *skb, u32 info); +int homa_err_handler_v6(struct sk_buff *skb, + struct inet6_skb_parm *opt, u8 type, u8 code, + int offset, __be32 info); +int homa_fill_data_interleaved(struct homa_rpc *rpc, + struct sk_buff *skb, struct iov_iter *iter); +void homa_freeze(struct homa_rpc *rpc, enum homa_freeze_type type, + char *format); +void homa_freeze_peers(struct homa *homa); +struct homa_gap *homa_gap_new(struct list_head *next, int start, int end); +void homa_gap_retry(struct homa_rpc *rpc); +int homa_get_port(struct sock *sk, unsigned short snum); +int homa_getsockopt(struct sock *sk, int level, int optname, + char __user *optval, int __user *option); +int homa_hash(struct sock *sk); +enum hrtimer_restart homa_hrtimer(struct hrtimer *timer); +int homa_init(struct homa *homa); +void homa_incoming_sysctl_changed(struct homa *homa); +int homa_ioc_abort(struct sock *sk, int *karg); +int homa_ioctl(struct sock *sk, int cmd, int *karg); +void homa_log_throttled(struct homa *homa); +int homa_message_in_init(struct homa_rpc *rpc, int length, + int unsched); +int homa_message_out_fill(struct homa_rpc *rpc, + struct iov_iter *iter, int xmit); +void homa_message_out_init(struct homa_rpc *rpc, int length); +void homa_need_ack_pkt(struct sk_buff *skb, struct homa_sock *hsk, + struct homa_rpc *rpc); +struct sk_buff *homa_new_data_packet(struct homa_rpc *rpc, + struct iov_iter *iter, int offset, + int length, int max_seg_data); +void homa_outgoing_sysctl_changed(struct homa *homa); +int homa_pacer_main(void *transportInfo); +void homa_pacer_stop(struct homa *homa); +void homa_pacer_xmit(struct homa *homa); +__poll_t homa_poll(struct file *file, struct socket *sock, + struct poll_table_struct *wait); +char *homa_print_ipv4_addr(__be32 addr); +char *homa_print_ipv6_addr(const struct in6_addr *addr); +char *homa_print_packet(struct sk_buff *skb, char *buffer, int buf_len); +char *homa_print_packet_short(struct sk_buff *skb, char *buffer, + int buf_len); +void homa_prios_changed(struct homa *homa); +int homa_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, + int flags, int *addr_len); +int homa_register_interests(struct homa_interest *interest, + struct homa_sock *hsk, int flags, __u64 id); +void homa_remove_from_throttled(struct homa_rpc *rpc); +void homa_resend_data(struct homa_rpc *rpc, int start, int end, + int priority); +void homa_resend_pkt(struct sk_buff *skb, struct homa_rpc *rpc, + struct homa_sock *hsk); +void homa_rpc_abort(struct homa_rpc *crpc, int error); +void homa_rpc_acked(struct homa_sock *hsk, + const struct in6_addr *saddr, struct homa_ack *ack); +void homa_rpc_free(struct homa_rpc *rpc); +void homa_rpc_handoff(struct homa_rpc *rpc); +int homa_sendmsg(struct sock *sk, struct msghdr *msg, size_t len); +int homa_setsockopt(struct sock *sk, int level, int optname, + sockptr_t optval, unsigned int optlen); +int homa_shutdown(struct socket *sock, int how); +int homa_snprintf(char *buffer, int size, int used, + const char *format, ...) __printf(4, 5); +int homa_softirq(struct sk_buff *skb); +void homa_spin(int ns); +char *homa_symbol_for_type(uint8_t type); #if LINUX_VERSION_CODE < KERNEL_VERSION(6, 12, 0) -extern int homa_sysctl_softirq_cores(struct ctl_table *table, - int write, void __user *buffer, size_t *lenp, loff_t *ppos); +int homa_sysctl_softirq_cores(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, + loff_t *ppos); #else -extern int homa_sysctl_softirq_cores(const struct ctl_table *table, - int write, void __user *buffer, size_t *lenp, loff_t *ppos); +int homa_sysctl_softirq_cores(const struct ctl_table *table, + int write, void *buffer, size_t *lenp, + loff_t *ppos); #endif -extern void homa_timer(struct homa *homa); -extern int homa_timer_main(void *transportInfo); -extern void homa_unhash(struct sock *sk); -extern void homa_unknown_pkt(struct sk_buff *skb, struct homa_rpc *rpc); -extern int homa_unsched_priority(struct homa *homa, - struct homa_peer *peer, int length); -extern int homa_validate_incoming(struct homa *homa, int verbose, - int *link_errors); -extern struct homa_rpc - *homa_wait_for_message(struct homa_sock *hsk, int flags, - __u64 id); -extern int homa_xmit_control(enum homa_packet_type type, void *contents, - size_t length, struct homa_rpc *rpc); -extern int __homa_xmit_control(void *contents, size_t length, - struct homa_peer *peer, struct homa_sock *hsk); -extern void homa_xmit_data(struct homa_rpc *rpc, bool force); -extern void __homa_xmit_data(struct sk_buff *skb, struct homa_rpc *rpc, - int priority); -extern void homa_xmit_unknown(struct sk_buff *skb, struct homa_sock *hsk); +void homa_timer(struct homa *homa); +int homa_timer_main(void *transportInfo); +void homa_unhash(struct sock *sk); +void homa_unknown_pkt(struct sk_buff *skb, struct homa_rpc *rpc); +int homa_unsched_priority(struct homa *homa, struct homa_peer *peer, + int length); +int homa_validate_incoming(struct homa *homa, int verbose, + int *link_errors); +struct homa_rpc *homa_wait_for_message(struct homa_sock *hsk, int flags, + __u64 id); +int homa_xmit_control(enum homa_packet_type type, void *contents, + size_t length, struct homa_rpc *rpc); +int __homa_xmit_control(void *contents, size_t length, + struct homa_peer *peer, struct homa_sock *hsk); +void homa_xmit_data(struct homa_rpc *rpc, bool force); +void __homa_xmit_data(struct sk_buff *skb, struct homa_rpc *rpc, + int priority); +void homa_xmit_unknown(struct sk_buff *skb, struct homa_sock *hsk); /** * homa_check_pacer() - This method is invoked at various places in Homa to diff --git a/homa_incoming.c b/homa_incoming.c index abf13ab..a8f17d8 100644 --- a/homa_incoming.c +++ b/homa_incoming.c @@ -217,6 +217,8 @@ void homa_add_packet(struct homa_rpc *rpc, struct sk_buff *skb) * will be RPC_DEAD. */ int homa_copy_to_user(struct homa_rpc *rpc) + __releases(rpc->bucket_lock) + __acquires(rpc->bucket_lock) { #ifdef __UNIT_TEST__ #define MAX_SKBS 3 @@ -295,8 +297,8 @@ int homa_copy_to_user(struct homa_rpc *rpc) } chunk_size = buf_bytes; } - error = import_ubuf(READ, dst, chunk_size, - &iter); + error = import_ubuf(READ, (void __user *)dst, + chunk_size, &iter); if (error) goto free_skbs; error = skb_copy_datagram_iter(skbs[i], @@ -861,6 +863,7 @@ void homa_need_ack_pkt(struct sk_buff *skb, struct homa_sock *hsk, */ void homa_ack_pkt(struct sk_buff *skb, struct homa_sock *hsk, struct homa_rpc *rpc) + __releases(rpc->bucket_lock) { const struct in6_addr saddr = skb_canonical_ipv6_saddr(skb); struct ack_header *h = (struct ack_header *)skb->data; @@ -1198,6 +1201,7 @@ int homa_register_interests(struct homa_interest *interest, */ struct homa_rpc *homa_wait_for_message(struct homa_sock *hsk, int flags, __u64 id) + __acquires(&rpc->bucket_lock) { uint64_t poll_start, poll_end, now; int error, blocked = 0, polled = 0; diff --git a/homa_metrics.h b/homa_metrics.h index 23d3ecf..f43db27 100644 --- a/homa_metrics.h +++ b/homa_metrics.h @@ -661,15 +661,15 @@ static inline struct homa_metrics *homa_metrics_per_cpu(void) #define INC_METRIC(metric, count) per_cpu(homa_metrics, \ raw_smp_processor_id()).metric += (count) -extern void homa_metric_append(struct homa *homa, const char *format, ...); -extern loff_t homa_metrics_lseek(struct file *file, loff_t offset, - int whence); -extern int homa_metrics_open(struct inode *inode, struct file *file); -extern char *homa_metrics_print(struct homa *homa); -extern ssize_t homa_metrics_read(struct file *file, char __user *buffer, - size_t length, loff_t *offset); -extern int homa_metrics_release(struct inode *inode, struct file *file); -extern int homa_proc_read_metrics(char *buffer, char **start, off_t offset, - int count, int *eof, void *data); - -#endif /* _HOMA_METRICS_H */ \ No newline at end of file +void homa_metric_append(struct homa *homa, const char *format, ...); +loff_t homa_metrics_lseek(struct file *file, loff_t offset, + int whence); +int homa_metrics_open(struct inode *inode, struct file *file); +char *homa_metrics_print(struct homa *homa); +ssize_t homa_metrics_read(struct file *file, char __user *buffer, + size_t length, loff_t *offset); +int homa_metrics_release(struct inode *inode, struct file *file); +int homa_proc_read_metrics(char *buffer, char **start, off_t offset, + int count, int *eof, void *data); + +#endif /* _HOMA_METRICS_H */ diff --git a/homa_offload.c b/homa_offload.c index 174d946..e1e7597 100644 --- a/homa_offload.c +++ b/homa_offload.c @@ -24,8 +24,8 @@ extern struct homa *homa; /* Pointers to TCP's net_offload structures. NULL means homa_gro_hook_tcp * hasn't been called yet. */ -const struct net_offload *tcp_net_offload; -const struct net_offload *tcp6_net_offload; +static const struct net_offload *tcp_net_offload; +static const struct net_offload *tcp6_net_offload; /* * Identical to *tcp_net_offload except that the gro_receive function @@ -91,15 +91,17 @@ void homa_gro_hook_tcp(void) return; pr_notice("Homa setting up TCP hijacking\n"); - tcp_net_offload = inet_offloads[IPPROTO_TCP]; + tcp_net_offload = rcu_dereference(inet_offloads[IPPROTO_TCP]); hook_tcp_net_offload = *tcp_net_offload; hook_tcp_net_offload.callbacks.gro_receive = homa_tcp_gro_receive; - inet_offloads[IPPROTO_TCP] = &hook_tcp_net_offload; + inet_offloads[IPPROTO_TCP] = (struct net_offload __rcu *) + &hook_tcp_net_offload; - tcp6_net_offload = inet6_offloads[IPPROTO_TCP]; + tcp6_net_offload = rcu_dereference(inet6_offloads[IPPROTO_TCP]); hook_tcp6_net_offload = *tcp6_net_offload; hook_tcp6_net_offload.callbacks.gro_receive = homa_tcp_gro_receive; - inet6_offloads[IPPROTO_TCP] = &hook_tcp6_net_offload; + inet6_offloads[IPPROTO_TCP] = (struct net_offload __rcu *) + &hook_tcp6_net_offload; } /** @@ -112,9 +114,11 @@ void homa_gro_unhook_tcp(void) if (tcp_net_offload == NULL) return; pr_notice("Homa cancelling TCP hijacking\n"); - inet_offloads[IPPROTO_TCP] = tcp_net_offload; + inet_offloads[IPPROTO_TCP] = (struct net_offload __rcu *) + tcp_net_offload; tcp_net_offload = NULL; - inet6_offloads[IPPROTO_TCP] = tcp6_net_offload; + inet6_offloads[IPPROTO_TCP] = (struct net_offload __rcu *) + tcp6_net_offload; tcp6_net_offload = NULL; } @@ -307,7 +311,7 @@ struct sk_buff *homa_gro_receive(struct list_head *held_list, // tt_record("homa_gro_receive can't pull enough data " // "from packet for trace"); if (h_new->common.type == DATA) { - if (h_new->seg.offset == -1) { + if (h_new->seg.offset == (__force __be32)-1) { tt_record2("homa_gro_receive replaced offset %d with %d", ntohl(h_new->seg.offset), ntohl(h_new->common.sequence)); diff --git a/homa_offload.h b/homa_offload.h index 6bf7915..2162891 100644 --- a/homa_offload.h +++ b/homa_offload.h @@ -73,22 +73,19 @@ struct homa_offload_core { }; DECLARE_PER_CPU(struct homa_offload_core, homa_offload_core); -extern int homa_gro_complete(struct sk_buff *skb, int thoff); -extern void homa_gro_gen2(struct sk_buff *skb); -extern void homa_gro_gen3(struct sk_buff *skb); -extern void homa_gro_hook_tcp(void); -extern void homa_gro_unhook_tcp(void); -extern struct sk_buff - *homa_gro_receive(struct list_head *gro_list, - struct sk_buff *skb); -extern struct sk_buff - *homa_gso_segment(struct sk_buff *skb, - netdev_features_t features); -extern int homa_offload_end(void); -extern int homa_offload_init(void); -extern void homa_send_ipis(void); -extern struct sk_buff - *homa_tcp_gro_receive(struct list_head *held_list, - struct sk_buff *skb); +int homa_gro_complete(struct sk_buff *skb, int thoff); +void homa_gro_gen2(struct sk_buff *skb); +void homa_gro_gen3(struct sk_buff *skb); +void homa_gro_hook_tcp(void); +void homa_gro_unhook_tcp(void); +struct sk_buff *homa_gro_receive(struct list_head *gro_list, + struct sk_buff *skb); +struct sk_buff *homa_gso_segment(struct sk_buff *skb, + netdev_features_t features); +int homa_offload_end(void); +int homa_offload_init(void); +void homa_send_ipis(void); +struct sk_buff *homa_tcp_gro_receive(struct list_head *held_list, + struct sk_buff *skb); #endif /* _HOMA_OFFLOAD_H */ diff --git a/homa_outgoing.c b/homa_outgoing.c index e3410a2..9d8ea65 100644 --- a/homa_outgoing.c +++ b/homa_outgoing.c @@ -28,7 +28,7 @@ void homa_message_out_init(struct homa_rpc *rpc, int length) if (rpc->msgout.unscheduled > length) rpc->msgout.unscheduled = length; rpc->msgout.sched_priority = 0; - rpc->msgout.init_ns= sched_clock(); + rpc->msgout.init_ns = sched_clock(); } /** @@ -132,7 +132,7 @@ struct sk_buff *homa_new_data_packet(struct homa_rpc *rpc, homa_peer_get_acks(rpc->peer, 1, &h->ack); h->cutoff_version = rpc->peer->cutoff_version; h->retransmit = 0; - h->seg.offset = -1; + h->seg.offset = htonl(-1); segs = length + max_seg_data - 1; do_div(segs, max_seg_data); @@ -195,6 +195,8 @@ struct sk_buff *homa_new_data_packet(struct homa_rpc *rpc, * rpc->state will be RPC_DEAD. */ int homa_message_out_fill(struct homa_rpc *rpc, struct iov_iter *iter, int xmit) + __releases(rpc->bucket_lock) + __acquires(rpc->bucket_lock) { /* Geometry information for packets: * mtu: largest size for an on-the-wire packet (including @@ -484,6 +486,8 @@ void homa_xmit_unknown(struct sk_buff *skb, struct homa_sock *hsk) * the NIC queue is sufficiently long. */ void homa_xmit_data(struct homa_rpc *rpc, bool force) + __releases(rpc->bucket_lock) + __acquires(rpc->bucket_lock) { struct homa *homa = rpc->hsk->homa; #if 1 /* See strip.py */ @@ -703,6 +707,7 @@ void homa_resend_data(struct homa_rpc *rpc, int start, int end, } resend_done: + return; } /** diff --git a/homa_peer.c b/homa_peer.c index 1a64348..7293409 100644 --- a/homa_peer.c +++ b/homa_peer.c @@ -153,11 +153,15 @@ struct homa_peer *homa_peer_find(struct homa_peertab *peertab, struct dst_entry *dst; // Should use siphash or jhash here: - __u32 bucket = hash_32(addr->in6_u.u6_addr32[0], HOMA_PEERTAB_BUCKET_BITS); - - bucket ^= hash_32(addr->in6_u.u6_addr32[1], HOMA_PEERTAB_BUCKET_BITS); - bucket ^= hash_32(addr->in6_u.u6_addr32[2], HOMA_PEERTAB_BUCKET_BITS); - bucket ^= hash_32(addr->in6_u.u6_addr32[3], HOMA_PEERTAB_BUCKET_BITS); + __u32 bucket = hash_32((__force __u32)addr->in6_u.u6_addr32[0], + HOMA_PEERTAB_BUCKET_BITS); + + bucket ^= hash_32((__force __u32)addr->in6_u.u6_addr32[1], + HOMA_PEERTAB_BUCKET_BITS); + bucket ^= hash_32((__force __u32)addr->in6_u.u6_addr32[2], + HOMA_PEERTAB_BUCKET_BITS); + bucket ^= hash_32((__force __u32)addr->in6_u.u6_addr32[3], + HOMA_PEERTAB_BUCKET_BITS); hlist_for_each_entry_rcu(peer, &peertab->buckets[bucket], peertab_links) { if (ipv6_addr_equal(&peer->addr, addr)) @@ -359,6 +363,7 @@ void homa_peer_set_cutoffs(struct homa_peer *peer, int c0, int c1, int c2, * @peer: Peer to lock. */ void homa_peer_lock_slow(struct homa_peer *peer) + __acquires(&peer->ack_lock) { __u64 start = sched_clock(); diff --git a/homa_peer.h b/homa_peer.h index 50fc2d2..babf1a5 100644 --- a/homa_peer.h +++ b/homa_peer.h @@ -222,6 +222,7 @@ void homa_peertab_gc_dsts(struct homa_peertab *peertab, __u64 now); * @peer: Peer to lock. */ static inline void homa_peer_lock(struct homa_peer *peer) + __acquires(&peer->ack_lock) { if (!spin_trylock_bh(&peer->ack_lock)) homa_peer_lock_slow(peer); @@ -232,6 +233,7 @@ static inline void homa_peer_lock(struct homa_peer *peer) * @peer: Peer to lock. */ static inline void homa_peer_unlock(struct homa_peer *peer) + __releases(&peer->ack_lock) { spin_unlock_bh(&peer->ack_lock); } diff --git a/homa_plumbing.c b/homa_plumbing.c index 96e3e06..0f89f83 100644 --- a/homa_plumbing.c +++ b/homa_plumbing.c @@ -17,14 +17,19 @@ MODULE_DESCRIPTION("Homa transport protocol"); MODULE_VERSION("0.01"); /* Not yet sure what these variables are for */ -long sysctl_homa_mem[3] __read_mostly; -int sysctl_homa_rmem_min __read_mostly; -int sysctl_homa_wmem_min __read_mostly; +static long sysctl_homa_mem[3] __read_mostly; +static int sysctl_homa_rmem_min __read_mostly; +static int sysctl_homa_wmem_min __read_mostly; /* Global data for Homa. Never reference homa_data directory. Always use * the homa variable instead; this allows overriding during unit tests. */ -struct homa homa_data; +static struct homa homa_data; + +/* This variable should almost never be used directly; it is normally + * passed as a parameter to functions that need it. Thus it is not declared + * in a header file. + */ struct homa *homa = &homa_data; /* True means that the Homa module is in the process of unloading itself, @@ -46,7 +51,7 @@ static int action; * be implemented by PF_INET6 functions that are independent of the * Homa protocol. */ -const struct proto_ops homa_proto_ops = { +static const struct proto_ops homa_proto_ops = { .family = PF_INET, .owner = THIS_MODULE, .release = inet_release, @@ -67,7 +72,7 @@ const struct proto_ops homa_proto_ops = { .set_peek_off = sk_set_peek_off, }; -const struct proto_ops homav6_proto_ops = { +static const struct proto_ops homav6_proto_ops = { .family = PF_INET6, .owner = THIS_MODULE, .release = inet6_release, @@ -94,7 +99,7 @@ const struct proto_ops homav6_proto_ops = { * protocol family, and in many cases they are invoked by functions in * homa_proto_ops. Most of these functions have Homa-specific implementations. */ -struct proto homa_prot = { +static struct proto homa_prot = { .name = "HOMA", .owner = THIS_MODULE, .close = homa_close, @@ -102,7 +107,7 @@ struct proto homa_prot = { .disconnect = homa_disconnect, .ioctl = homa_ioctl, .init = homa_socket, - .destroy = 0, + .destroy = NULL, .setsockopt = homa_setsockopt, .getsockopt = homa_getsockopt, .sendmsg = homa_sendmsg, @@ -118,7 +123,7 @@ struct proto homa_prot = { .no_autobind = 1, }; -struct proto homav6_prot = { +static struct proto homav6_prot = { .name = "HOMAv6", .owner = THIS_MODULE, .close = homa_close, @@ -126,7 +131,7 @@ struct proto homav6_prot = { .disconnect = homa_disconnect, .ioctl = homa_ioctl, .init = homa_socket, - .destroy = 0, + .destroy = NULL, .setsockopt = homa_setsockopt, .getsockopt = homa_getsockopt, .sendmsg = homa_sendmsg, @@ -147,7 +152,7 @@ struct proto homav6_prot = { }; /* Top-level structure describing the Homa protocol. */ -struct inet_protosw homa_protosw = { +static struct inet_protosw homa_protosw = { .type = SOCK_DGRAM, .protocol = IPPROTO_HOMA, .prot = &homa_prot, @@ -155,7 +160,7 @@ struct inet_protosw homa_protosw = { .flags = INET_PROTOSW_REUSE, }; -struct inet_protosw homav6_protosw = { +static struct inet_protosw homav6_protosw = { .type = SOCK_DGRAM, .protocol = IPPROTO_HOMA, .prot = &homav6_prot, @@ -745,7 +750,7 @@ int homa_ioc_abort(struct sock *sk, int *karg) struct homa_abort_args args; struct homa_rpc *rpc; - if (unlikely(copy_from_user(&args, (void *)karg, sizeof(args)))) + if (unlikely(copy_from_user(&args, (void __user *)karg, sizeof(args)))) return -EFAULT; if (args._pad1 || args._pad2[0] || args._pad2[1]) @@ -824,8 +829,8 @@ int homa_socket(struct sock *sk) * @optlen: Number of bytes of data at @optval. * Return: 0 on success, otherwise a negative errno. */ -int homa_setsockopt(struct sock *sk, int level, int optname, sockptr_t optval, - unsigned int optlen) +int homa_setsockopt(struct sock *sk, int level, int optname, + sockptr_t optval, unsigned int optlen) { struct homa_sock *hsk = homa_sk(sk); struct homa_set_buf_args args; @@ -842,7 +847,7 @@ int homa_setsockopt(struct sock *sk, int level, int optname, sockptr_t optval, /* Do a trivial test to make sure we can at least write the first * page of the region. */ - if (copy_to_user(args.start, &args, sizeof(args))) + if (copy_to_user((void __user *)args.start, &args, sizeof(args))) return -EFAULT; homa_sock_lock(hsk, "homa_setsockopt SO_HOMA_SET_BUF"); @@ -888,13 +893,15 @@ int homa_sendmsg(struct sock *sk, struct msghdr *msg, size_t length) struct homa_rpc *rpc = NULL; union sockaddr_in_union *addr = (union sockaddr_in_union *)msg->msg_name; - per_cpu(homa_offload_core, raw_smp_processor_id()).last_app_active = start; + per_cpu(homa_offload_core, raw_smp_processor_id()).last_app_active = + start; if (unlikely(!msg->msg_control_is_user)) { tt_record("homa_sendmsg error: !msg->msg_control_is_user"); result = -EINVAL; goto error; } - if (unlikely(copy_from_user(&args, msg->msg_control, sizeof(args)))) { + if (unlikely(copy_from_user(&args, (void __user *)msg->msg_control, + sizeof(args)))) { result = -EFAULT; goto error; } @@ -932,8 +939,8 @@ int homa_sendmsg(struct sock *sk, struct msghdr *msg, size_t length) homa_rpc_unlock(rpc); rpc = NULL; - if (unlikely(copy_to_user(msg->msg_control, &args, - sizeof(args)))) { + if (unlikely(copy_to_user((void __user *)msg->msg_control, + &args, sizeof(args)))) { rpc = homa_find_client_rpc(hsk, args.id); result = -EFAULT; goto error; @@ -973,7 +980,7 @@ int homa_sendmsg(struct sock *sk, struct msghdr *msg, size_t length) tt_record2("homa_sendmsg error: RPC id %d in bad state %d", rpc->id, rpc->state); homa_rpc_unlock(rpc); - rpc = 0; + rpc = NULL; result = -EINVAL; goto error; } @@ -1032,7 +1039,7 @@ int homa_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int flags, result = -EINVAL; goto done; } - if (unlikely(copy_from_user(&control, msg->msg_control, + if (unlikely(copy_from_user(&control, (void __user *)msg->msg_control, sizeof(control)))) { result = -EFAULT; goto done; @@ -1130,7 +1137,8 @@ int homa_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int flags, homa_rpc_unlock(rpc); done: - if (unlikely(copy_to_user(msg->msg_control, &control, sizeof(control)))) { + if (unlikely(copy_to_user((void __user *)msg->msg_control, &control, + sizeof(control)))) { /* Note: in this case the message's buffers will be leaked. */ pr_notice("%s couldn't copy back args\n", __func__); result = -EFAULT; @@ -1374,7 +1382,7 @@ int homa_err_handler_v4(struct sk_buff *skb, u32 info) iph = (struct iphdr *)(icmp + sizeof(struct icmphdr)); h = (struct common_header *)(icmp + sizeof(struct icmphdr) + iph->ihl * 4); - homa_abort_rpcs(homa, &saddr, htons(h->dport), -ENOTCONN); + homa_abort_rpcs(homa, &saddr, ntohs(h->dport), -ENOTCONN); } else if (type == ICMP_DEST_UNREACH) { int error; @@ -1383,7 +1391,7 @@ int homa_err_handler_v4(struct sk_buff *skb, u32 info) else error = -EHOSTUNREACH; tt_record2("ICMP destination unreachable: 0x%x (daddr 0x%x)", - iph->saddr, iph->daddr); + ntohl(iph->saddr), ntohl(iph->daddr)); homa_abort_rpcs(homa, &saddr, 0, error); } else { pr_notice("%s invoked with info %x, ICMP type %d, ICMP code %d\n", @@ -1416,7 +1424,7 @@ int homa_err_handler_v6(struct sk_buff *skb, struct inet6_skb_parm *opt, iph = (struct ipv6hdr *)(icmp + sizeof(struct icmphdr)); h = (struct common_header *)(icmp + sizeof(struct icmphdr) + HOMA_IPV6_HEADER_LENGTH); - homa_abort_rpcs(homa, &iph->daddr, htons(h->dport), -ENOTCONN); + homa_abort_rpcs(homa, &iph->daddr, ntohs(h->dport), -ENOTCONN); } else if (type == ICMPV6_DEST_UNREACH) { int error; @@ -1450,7 +1458,7 @@ __poll_t homa_poll(struct file *file, struct socket *sock, struct poll_table_struct *wait) { struct sock *sk = sock->sk; - __poll_t mask; + __u32 mask; /* It seems to be standard practice for poll functions *not* to * acquire the socket lock, so we don't do it here; not sure @@ -1463,7 +1471,7 @@ __poll_t homa_poll(struct file *file, struct socket *sock, if (!list_empty(&homa_sk(sk)->ready_requests) || !list_empty(&homa_sk(sk)->ready_responses)) mask |= POLLIN | POLLRDNORM; - return mask; + return (__poll_t)mask; } /** @@ -1483,7 +1491,7 @@ int homa_dointvec(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos) #else int homa_dointvec(const struct ctl_table *table, int write, - void __user *buffer, size_t *lenp, loff_t *ppos) + void *buffer, size_t *lenp, loff_t *ppos) #endif { int result; @@ -1564,7 +1572,7 @@ int homa_sysctl_softirq_cores(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos) #else int homa_sysctl_softirq_cores(const struct ctl_table *table, int write, - void __user *buffer, size_t *lenp, loff_t *ppos) + void *buffer, size_t *lenp, loff_t *ppos) #endif { struct homa_offload_core *offload_core; diff --git a/homa_rpc.c b/homa_rpc.c index 9baca39..9f93818 100644 --- a/homa_rpc.c +++ b/homa_rpc.c @@ -21,6 +21,7 @@ */ struct homa_rpc *homa_rpc_new_client(struct homa_sock *hsk, const union sockaddr_in_union *dest) + __acquires(&crpc->bucket->lock) { struct in6_addr dest_addr_as_ipv6 = canonical_ipv6_addr(dest); struct homa_rpc_bucket *bucket; @@ -108,6 +109,7 @@ struct homa_rpc *homa_rpc_new_client(struct homa_sock *hsk, struct homa_rpc *homa_rpc_new_server(struct homa_sock *hsk, const struct in6_addr *source, struct data_header *h, int *created) + __acquires(&srpc->bucket->lock) { __u64 id = homa_local_id(h->common.sender_id); struct homa_rpc_bucket *bucket; @@ -244,6 +246,8 @@ void homa_rpc_acked(struct homa_sock *hsk, const struct in6_addr *saddr, * not be locked. */ void homa_rpc_free(struct homa_rpc *rpc) + __acquires(&rpc->hsk->lock) + __releases(&rpc->hsk->lock) { /* The goal for this function is to make the RPC inaccessible, * so that no other code will ever access it again. However, don't @@ -369,7 +373,7 @@ int homa_rpc_reap(struct homa_sock *hsk, int count) /* Collect buffers and freeable RPCs. */ list_for_each_entry_rcu(rpc, &hsk->dead_rpcs, dead_links) { if ((atomic_read(&rpc->flags) & RPC_CANT_REAP) || - atomic_read(&rpc->grants_in_progress)!= 0 || + atomic_read(&rpc->grants_in_progress) != 0 || atomic_read(&rpc->msgout.active_xmits) != 0) { INC_METRIC(disabled_rpc_reaps, 1); continue; @@ -479,6 +483,7 @@ int homa_rpc_reap(struct homa_sock *hsk, int count) * by invoking homa_rpc_unlock. */ struct homa_rpc *homa_find_client_rpc(struct homa_sock *hsk, __u64 id) + __acquires(&crpc->bucket->lock) { struct homa_rpc_bucket *bucket = homa_client_rpc_bucket(hsk, id); struct homa_rpc *crpc; @@ -507,6 +512,7 @@ struct homa_rpc *homa_find_client_rpc(struct homa_sock *hsk, __u64 id) struct homa_rpc *homa_find_server_rpc(struct homa_sock *hsk, const struct in6_addr *saddr, __u16 sport, __u64 id) + __acquires(&srpc->bucket->lock) { struct homa_rpc_bucket *bucket = homa_server_rpc_bucket(hsk, id); struct homa_rpc *srpc; diff --git a/homa_skb.c b/homa_skb.c index dede213..07aeb21 100644 --- a/homa_skb.c +++ b/homa_skb.c @@ -257,7 +257,7 @@ bool homa_skb_page_alloc(struct homa *homa, struct homa_skb_core *skb_core) skb_core->page_inuse = 0; if (skb_core->num_stashed_pages > 0) { skb_core->num_stashed_pages--; - skb_core->skb_page =skb_core->stashed_pages[ + skb_core->skb_page = skb_core->stashed_pages[ skb_core->num_stashed_pages]; goto success; } diff --git a/homa_skb.h b/homa_skb.h index fd52919..db61767 100644 --- a/homa_skb.h +++ b/homa_skb.h @@ -96,29 +96,30 @@ struct homa_skb_core { }; DECLARE_PER_CPU(struct homa_skb_core, homa_skb_core); -extern int homa_skb_append_from_iter(struct homa *homa, - struct sk_buff *skb, struct iov_iter *iter, int length); -extern int homa_skb_append_from_skb(struct homa *homa, - struct sk_buff *dst_skb, struct sk_buff *src_skb, - int offset, int length); -extern int homa_skb_append_to_frag(struct homa *homa, struct sk_buff *skb, - void *buf, int length); -extern void homa_skb_cache_pages(struct homa *homa, struct page **pages, - int count); -extern void homa_skb_cleanup(struct homa *homa); -extern void *homa_skb_extend_frags(struct homa *homa, struct sk_buff *skb, - int *length); -extern void homa_skb_free_tx(struct homa *homa, struct sk_buff *skb); -extern void homa_skb_free_many_tx(struct homa *homa, struct sk_buff **skbs, - int count); -extern void homa_skb_get(struct sk_buff *skb, void *dest, int offset, - int length); -extern int homa_skb_init(struct homa *homa); -extern struct sk_buff - *homa_skb_new_tx(int length); -extern bool homa_skb_page_alloc(struct homa *homa, - struct homa_skb_core *core); -extern void homa_skb_release_pages(struct homa *homa); -extern void homa_skb_stash_pages(struct homa *homa, int length); - -#endif /* _HOMA_SKB_H */ \ No newline at end of file +int homa_skb_append_from_iter(struct homa *homa, + struct sk_buff *skb, struct iov_iter *iter, + int length); +int homa_skb_append_from_skb(struct homa *homa, + struct sk_buff *dst_skb, + struct sk_buff *src_skb, int offset, + int length); +int homa_skb_append_to_frag(struct homa *homa, struct sk_buff *skb, + void *buf, int length); +void homa_skb_cache_pages(struct homa *homa, struct page **pages, + int count); +void homa_skb_cleanup(struct homa *homa); +void *homa_skb_extend_frags(struct homa *homa, struct sk_buff *skb, + int *length); +void homa_skb_free_tx(struct homa *homa, struct sk_buff *skb); +void homa_skb_free_many_tx(struct homa *homa, struct sk_buff **skbs, + int count); +void homa_skb_get(struct sk_buff *skb, void *dest, int offset, + int length); +int homa_skb_init(struct homa *homa); +struct sk_buff *homa_skb_new_tx(int length); +bool homa_skb_page_alloc(struct homa *homa, + struct homa_skb_core *core); +void homa_skb_release_pages(struct homa *homa); +void homa_skb_stash_pages(struct homa *homa, int length); + +#endif /* _HOMA_SKB_H */ diff --git a/homa_sock.c b/homa_sock.c index 521f084..9f01b2c 100644 --- a/homa_sock.c +++ b/homa_sock.c @@ -90,17 +90,19 @@ struct homa_sock *homa_socktab_next(struct homa_socktab_scan *scan) while (1) { while (!scan->next) { + struct hlist_head *bucket; + scan->current_bucket++; if (scan->current_bucket >= HOMA_SOCKTAB_BUCKETS) return NULL; + bucket = &scan->socktab->buckets[scan->current_bucket]; scan->next = (struct homa_socktab_links *) - hlist_first_rcu(&scan->socktab->buckets - [scan->current_bucket]); + rcu_dereference(hlist_first_rcu(bucket)); } links = scan->next; hsk = links->sock; - scan->next = (struct homa_socktab_links *)hlist_next_rcu(&links - ->hash_links); + scan->next = (struct homa_socktab_links *) + rcu_dereference(hlist_next_rcu(&links->hash_links)); return hsk; } } @@ -116,6 +118,7 @@ void homa_socktab_end_scan(struct homa_socktab_scan *scan) list_del(&scan->scan_links); spin_unlock_bh(&scan->socktab->write_lock); } + /** * homa_sock_init() - Constructor for homa_sock objects. This function * initializes only the parts of the socket that are owned by Homa. @@ -195,10 +198,10 @@ void homa_sock_unlink(struct homa_sock *hsk) */ spin_lock_bh(&socktab->write_lock); list_for_each_entry(scan, &socktab->active_scans, scan_links) { - if (!scan->next || (scan->next->sock != hsk)) + if (!scan->next || scan->next->sock != hsk) continue; - scan->next = (struct homa_socktab_links *)hlist_next_rcu( - &scan->next->hash_links); + scan->next = (struct homa_socktab_links *)rcu_dereference( + hlist_next_rcu(&scan->next->hash_links)); } hlist_del_rcu(&hsk->socktab_links.hash_links); spin_unlock_bh(&socktab->write_lock); @@ -211,6 +214,8 @@ void homa_sock_unlink(struct homa_sock *hsk) * @hsk: Socket to shut down. */ void homa_sock_shutdown(struct homa_sock *hsk) + __acquires(&hsk->lock) + __releases(&hsk->lock) { struct homa_interest *interest; struct homa_rpc *rpc; @@ -362,6 +367,7 @@ struct homa_sock *homa_sock_find(struct homa_socktab *socktab, __u16 port) * @hsk: socket to lock. */ void homa_sock_lock_slow(struct homa_sock *hsk) + __acquires(&hsk->lock) { __u64 start = sched_clock(); @@ -382,6 +388,7 @@ void homa_sock_lock_slow(struct homa_sock *hsk) * share a single bucket lock). */ void homa_bucket_lock_slow(struct homa_rpc_bucket *bucket, __u64 id) + __acquires(&bucket->lock) { __u64 start = sched_clock(); diff --git a/homa_sock.h b/homa_sock.h index aaccb41..5c83211 100644 --- a/homa_sock.h +++ b/homa_sock.h @@ -278,7 +278,7 @@ void homa_socktab_end_scan(struct homa_socktab_scan *scan); void homa_socktab_init(struct homa_socktab *socktab); struct homa_sock *homa_socktab_next(struct homa_socktab_scan *scan); struct homa_sock *homa_socktab_start_scan(struct homa_socktab *socktab, - struct homa_socktab_scan *scan); + struct homa_socktab_scan *scan); /** * homa_sock_lock() - Acquire the lock for a socket. If the socket @@ -288,6 +288,7 @@ struct homa_sock *homa_socktab_start_scan(struct homa_socktab *socktab, * used to track down deadlocks. */ static inline void homa_sock_lock(struct homa_sock *hsk, const char *locker) + __acquires(&hsk->lock) { if (!spin_trylock_bh(&hsk->lock)) { // printk(KERN_NOTICE "Slow path for socket %d, last locker %s", @@ -302,6 +303,7 @@ static inline void homa_sock_lock(struct homa_sock *hsk, const char *locker) * @hsk: Socket to lock. */ static inline void homa_sock_unlock(struct homa_sock *hsk) + __releases(&hsk->lock) { spin_unlock_bh(&hsk->lock); } @@ -398,6 +400,7 @@ static inline int homa_bucket_try_lock(struct homa_rpc_bucket *bucket, * @id: ID of the RPC that was using the lock. */ static inline void homa_bucket_unlock(struct homa_rpc_bucket *bucket, __u64 id) + __releases(&bucket->lock) { spin_unlock_bh(&bucket->lock); } diff --git a/homa_utils.c b/homa_utils.c index 1c114a6..da0273b 100644 --- a/homa_utils.c +++ b/homa_utils.c @@ -58,18 +58,19 @@ int homa_init(struct homa *homa) homa->next_client_port = HOMA_MIN_DEFAULT_PORT; homa->port_map = kmalloc(sizeof(*homa->port_map), GFP_KERNEL); if (!homa->port_map) { - pr_err("homa_init could create port_map: kmalloc failure"); + pr_err("%s couldn't create port_map: kmalloc failure", __func__); return -ENOMEM; } homa_socktab_init(homa->port_map); homa->peers = kmalloc(sizeof(*homa->peers), GFP_KERNEL); if (!homa->peers) { - pr_err("homa_init could create peers: kmalloc failure"); + pr_err("%s couldn't create peers: kmalloc failure", __func__); return -ENOMEM; } err = homa_peertab_init(homa->peers); if (err) { - pr_err("Couldn't initialize peer table (errno %d)\n", -err); + pr_err("%s couldn't initialize peer table (errno %d)\n", + __func__, -err); return err; } err = homa_skb_init(homa); @@ -310,7 +311,7 @@ char *homa_print_packet(struct sk_buff *skb, char *buffer, int buf_len) ", message_length %d, offset %d, data_length %d, incoming %d", ntohl(h->message_length), offset, seg_length, ntohl(h->incoming)); - if (ntohs(h->cutoff_version != 0)) + if (ntohs(h->cutoff_version) != 0) used = homa_snprintf(buffer, buf_len, used, ", cutoff_version %d", ntohs(h->cutoff_version)); @@ -686,6 +687,7 @@ void homa_spin(int ns) * @homa: Overall data about the Homa protocol implementation. */ void homa_throttle_lock_slow(struct homa *homa) + __acquires(&homa->throttle_lock) { __u64 start = sched_clock();