diff --git a/homa_qdisc.c b/homa_qdisc.c index b84ef03c..a352faa9 100755 --- a/homa_qdisc.c +++ b/homa_qdisc.c @@ -753,7 +753,7 @@ void homa_qdisc_defer_homa(struct homa_qdisc_dev *qdev, struct sk_buff *skb) h = (struct homa_data_hdr *)skb_transport_header(skb); bytes_left = rpc->msgout.length - ntohl(h->seg.offset); if (bytes_left < rpc->qrpc.tx_left) - rpc->qrpc.tx_left = bytes_left; + WRITE_ONCE(rpc->qrpc.tx_left, bytes_left); rpc->qrpc.qdev = qdev; homa_qdisc_insert_rb(qdev, rpc); } @@ -950,7 +950,7 @@ struct sk_buff *homa_qdisc_get_deferred_homa(struct homa_qdisc_dev *qdev) bytes_left = rpc->msgout.length - (ntohl(h->seg.offset) + info->data_bytes); if (bytes_left < qrpc->tx_left) - qrpc->tx_left = bytes_left; + WRITE_ONCE(qrpc->tx_left, bytes_left); if (fifo) { if (skb_queue_len(&qrpc->packets) > 0) { rb_erase_cached(node, &qdev->deferred_rpcs); diff --git a/homa_qdisc.h b/homa_qdisc.h index c5451644..eedd1e6b 100644 --- a/homa_qdisc.h +++ b/homa_qdisc.h @@ -484,10 +484,11 @@ static inline bool homa_qdisc_precedes(struct homa_rpc *rpc1, static inline int homa_qdisc_deferred_offset(struct homa_rpc *rpc) { /* This doesn't synchronize, but the worst that can happen is - * to return a slightly out-of-date result. + * to return a slightly out-of-date result. The pacer modifies + * these fields concurrently, under qdev->defer_lock. */ - if (skb_queue_len(&rpc->qrpc.packets) > 0) - return rpc->msgout.length - rpc->qrpc.tx_left; + if (skb_queue_len_lockless(&rpc->qrpc.packets) > 0) + return rpc->msgout.length - READ_ONCE(rpc->qrpc.tx_left); return -1; }