[Drbd-dev] [PATCH -next] drbd: Annotate RCU pointers as __rcu to fix sparse errors

Chen Jiahao chenjiahao16 at huawei.com
Tue Aug 1 11:42:45 CEST 2023


This patch adds __rcu annotation to RCU protected pointers,
in order to fix following sparse errors:

drbd_state.c:1908:30: error: incompatible types in comparison expression
drbd_state.c:834:22: error: incompatible types in comparison expression
drbd_state.c:838:14: error: incompatible types in comparison expression
drbd_state.c:1064:22: error: incompatible types in comparison expression
drbd_state.c:2075:17: error: incompatible types in comparison expression
drbd_nl.c:454:33: error: incompatible types in comparison expression
drbd_nl.c:691:38: error: incompatible types in comparison expression
drbd_nl.c:983:18: error: incompatible types in comparison expression
drbd_nl.c:1285:22: error: incompatible types in comparison expression
drbd_nl.c:1577:17: error: incompatible types in comparison expression
drbd_nl.c:1587:17: error: incompatible types in comparison expression
drbd_nl.c:1812:14: error: incompatible types in comparison expression
drbd_nl.c:2072:39: error: incompatible types in comparison expression
drbd_nl.c:2080:13: error: incompatible types in comparison expression
drbd_nl.c:2265:50: error: incompatible types in comparison expression
drbd_nl.c:2288:45: error: incompatible types in comparison expression
drbd_nl.c:2433:9: error: incompatible types in comparison expression
drbd_nl.c:2596:9: error: incompatible types in comparison expression
drbd_nl.c:2829:18: error: incompatible types in comparison expression
drbd_nl.c:2869:17: error: incompatible types in comparison expression
drbd_nl.c:3407:33: error: incompatible types in comparison expression
drbd_nl.c:3532:28: error: incompatible types in comparison expression
drbd_nl.c:3745:29: error: incompatible types in comparison expression
drbd_nl.c:3751:22: error: incompatible types in comparison expression
drbd_nl.c:3941:38: error: incompatible types in comparison expression
...

Also, introducing rcu_assign_pointer() and rcu_dereference()
to properly use these RCU protected pointers.

Signed-off-by: Chen Jiahao <chenjiahao16 at huawei.com>
---
 drivers/block/drbd/drbd_int.h   |  6 +++---
 drivers/block/drbd/drbd_nl.c    | 26 +++++++++++++-------------
 drivers/block/drbd/drbd_state.c |  2 +-
 3 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index a30a5ed811be..f97020cd5052 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -526,7 +526,7 @@ struct drbd_backing_dev {
 	struct block_device *backing_bdev;
 	struct block_device *md_bdev;
 	struct drbd_md md;
-	struct disk_conf *disk_conf; /* RCU, for updates: resource->conf_update */
+	struct disk_conf __rcu *disk_conf; /* RCU, for updates: resource->conf_update */
 	sector_t known_size; /* last known size of that backing device */
 };
 
@@ -629,7 +629,7 @@ struct drbd_connection {
 	unsigned int connect_cnt;	/* Inc each time a connection is established */
 
 	unsigned long flags;
-	struct net_conf *net_conf;	/* content protected by rcu */
+	struct net_conf __rcu *net_conf;	/* content protected by rcu */
 	wait_queue_head_t ping_wait;	/* Woken upon reception of a ping, and a state change */
 
 	struct sockaddr_storage my_addr;
@@ -889,7 +889,7 @@ struct drbd_device {
 	int rs_last_events;  /* counter of read or write "events" (unit sectors)
 			      * on the lower level device when we last looked. */
 	int c_sync_rate; /* current resync rate after syncer throttle magic */
-	struct fifo_buffer *rs_plan_s; /* correction values of resync planer (RCU, connection->conn_update) */
+	struct fifo_buffer __rcu *rs_plan_s; /* correction values of resync planer (RCU, connection->conn_update) */
 	int rs_in_flight; /* resync sectors in flight (to proxy, in proxy and from proxy) */
 	atomic_t ap_in_flight; /* App sectors in flight (waiting for ack) */
 	unsigned int peer_max_bio_size;
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index cddae6f4b00f..a63f1b4aae5b 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -722,7 +722,7 @@ drbd_set_role(struct drbd_device *const device, enum drbd_role new_role, int for
 		}
 	} else {
 		mutex_lock(&device->resource->conf_update);
-		nc = connection->net_conf;
+		nc = rcu_dereference(connection->net_conf);
 		if (nc)
 			nc->discard_my_data = 0; /* without copy; single bit op is atomic */
 		mutex_unlock(&device->resource->conf_update);
@@ -1531,7 +1531,7 @@ int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info)
 	}
 
 	mutex_lock(&device->resource->conf_update);
-	old_disk_conf = device->ldev->disk_conf;
+	old_disk_conf = rcu_dereference(device->ldev->disk_conf);
 	*new_disk_conf = *old_disk_conf;
 	if (should_set_defaults(info))
 		set_disk_conf_defaults(new_disk_conf);
@@ -1552,7 +1552,7 @@ int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info)
 		new_disk_conf->c_plan_ahead = DRBD_C_PLAN_AHEAD_MAX;
 
 	fifo_size = (new_disk_conf->c_plan_ahead * 10 * SLEEP_TIME) / HZ;
-	if (fifo_size != device->rs_plan_s->size) {
+	if (fifo_size != rcu_dereference(device->rs_plan_s)->size) {
 		new_plan = fifo_alloc(fifo_size);
 		if (!new_plan) {
 			drbd_err(device, "kmalloc of fifo_buffer failed");
@@ -1583,7 +1583,7 @@ int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info)
 		goto fail_unlock;
 
 	if (new_plan) {
-		old_plan = device->rs_plan_s;
+		old_plan = rcu_dereference(device->rs_plan_s);
 		rcu_assign_pointer(device->rs_plan_s, new_plan);
 	}
 
@@ -1715,7 +1715,7 @@ void drbd_backing_dev_free(struct drbd_device *device, struct drbd_backing_dev *
 			  ldev->md_bdev != ldev->backing_bdev);
 	close_backing_dev(device, ldev->backing_bdev, device, true);
 
-	kfree(ldev->disk_conf);
+	kfree(rcu_dereference(ldev->disk_conf));
 	kfree(ldev);
 }
 
@@ -1784,7 +1784,7 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info)
 		retcode = ERR_NOMEM;
 		goto fail;
 	}
-	nbc->disk_conf = new_disk_conf;
+	rcu_assign_pointer(nbc->disk_conf, new_disk_conf);
 
 	set_disk_conf_defaults(new_disk_conf);
 	err = disk_conf_from_attrs(new_disk_conf, info);
@@ -1934,10 +1934,10 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info)
 
 	/* Prevent shrinking of consistent devices ! */
 	{
-	unsigned long long nsz = drbd_new_dev_size(device, nbc, nbc->disk_conf->disk_size, 0);
+	unsigned long long nsz = drbd_new_dev_size(device, nbc, rcu_dereference(nbc->disk_conf)->disk_size, 0);
 	unsigned long long eff = nbc->md.la_size_sect;
 	if (drbd_md_test_flag(nbc, MDF_CONSISTENT) && nsz < eff) {
-		if (nsz == nbc->disk_conf->disk_size) {
+		if (nsz == rcu_dereference(nbc->disk_conf)->disk_size) {
 			drbd_warn(device, "truncating a consistent device during attach (%llu < %llu)\n", nsz, eff);
 		} else {
 			drbd_warn(device, "refusing to truncate a consistent device (%llu < %llu)\n", nsz, eff);
@@ -1971,7 +1971,7 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info)
 	D_ASSERT(device, device->ldev == NULL);
 	device->ldev = nbc;
 	device->resync = resync_lru;
-	device->rs_plan_s = new_plan;
+	rcu_assign_pointer(device->rs_plan_s, new_plan);
 	nbc = NULL;
 	resync_lru = NULL;
 	new_disk_conf = NULL;
@@ -2130,7 +2130,7 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info)
 	conn_reconfig_done(connection);
 	if (nbc) {
 		close_backing_dev(device, nbc->md_bdev,
-			  nbc->disk_conf->meta_dev_idx < 0 ?
+			  rcu_dereference(nbc->disk_conf)->meta_dev_idx < 0 ?
 				(void *)device : (void *)drbd_m_holder,
 			  nbc->md_bdev != nbc->backing_bdev);
 		close_backing_dev(device, nbc->backing_bdev, device, true);
@@ -2389,7 +2389,7 @@ int drbd_adm_net_opts(struct sk_buff *skb, struct genl_info *info)
 
 	mutex_lock(&connection->data.mutex);
 	mutex_lock(&connection->resource->conf_update);
-	old_net_conf = connection->net_conf;
+	old_net_conf = rcu_dereference(connection->net_conf);
 
 	if (!old_net_conf) {
 		drbd_msg_put_info(adm_ctx.reply_skb, "net conf missing, try connect");
@@ -2587,7 +2587,7 @@ int drbd_adm_connect(struct sk_buff *skb, struct genl_info *info)
 	drbd_flush_workqueue(&connection->sender_work);
 
 	mutex_lock(&adm_ctx.resource->conf_update);
-	old_net_conf = connection->net_conf;
+	old_net_conf = rcu_dereference(connection->net_conf);
 	if (old_net_conf) {
 		retcode = ERR_NET_CONFIGURED;
 		mutex_unlock(&adm_ctx.resource->conf_update);
@@ -2863,7 +2863,7 @@ int drbd_adm_resize(struct sk_buff *skb, struct genl_info *info)
 
 	if (new_disk_conf) {
 		mutex_lock(&device->resource->conf_update);
-		old_disk_conf = device->ldev->disk_conf;
+		old_disk_conf = rcu_dereference(device->ldev->disk_conf);
 		*new_disk_conf = *old_disk_conf;
 		new_disk_conf->disk_size = (sector_t)rs.resize_size;
 		rcu_assign_pointer(device->ldev->disk_conf, new_disk_conf);
diff --git a/drivers/block/drbd/drbd_state.c b/drivers/block/drbd/drbd_state.c
index 287a8d1d3f70..e9fa2dfe0dd8 100644
--- a/drivers/block/drbd/drbd_state.c
+++ b/drivers/block/drbd/drbd_state.c
@@ -2069,7 +2069,7 @@ static int w_after_conn_state_ch(struct drbd_work *w, int unused)
 		mutex_unlock(&notification_mutex);
 
 		mutex_lock(&connection->resource->conf_update);
-		old_conf = connection->net_conf;
+		old_conf = rcu_dereference(connection->net_conf);
 		connection->my_addr_len = 0;
 		connection->peer_addr_len = 0;
 		RCU_INIT_POINTER(connection->net_conf, NULL);
-- 
2.34.1



More information about the drbd-dev mailing list