From 05f7a7d6a7d23a877063857cf2df1dffec5a96dc Mon Sep 17 00:00:00 2001 From: Andreas Gruenbacher Date: Mon, 8 Aug 2011 23:36:56 +0200 Subject: idr: Add new function idr_is_empty() Signed-off-by: Andreas Gruenbacher Signed-off-by: Philipp Reisner --- include/linux/idr.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/idr.h b/include/linux/idr.h index 871a213a8477..9c95d210458b 100644 --- a/include/linux/idr.h +++ b/include/linux/idr.h @@ -85,6 +85,7 @@ void idr_remove(struct idr *idp, int id); void idr_free(struct idr *idp, int id); void idr_destroy(struct idr *idp); void idr_init(struct idr *idp); +bool idr_is_empty(struct idr *idp); /** * idr_preload_end - end preload section started with idr_preload() -- cgit v1.2.3-59-g8ed1b From 05a10ec7900dbdba008a24bf56b3490c4b568d2c Mon Sep 17 00:00:00 2001 From: Andreas Gruenbacher Date: Tue, 7 Jun 2011 22:54:17 +0200 Subject: drbd: Improve some function and variable naming Rename functions conn_destroy() -> drbd_destroy_connection(), drbd_minor_destroy() -> drbd_destroy_device() drbd_adm_add_minor() -> drbd_adm_add_minor() drbd_adm_delete_minor() -> drbd_adm_del_minor() Rename global variable minors to drbd_devices Signed-off-by: Andreas Gruenbacher Signed-off-by: Philipp Reisner --- drivers/block/drbd/drbd_int.h | 8 ++++---- drivers/block/drbd/drbd_main.c | 32 ++++++++++++++++---------------- drivers/block/drbd/drbd_nl.c | 32 ++++++++++++++++---------------- drivers/block/drbd/drbd_proc.c | 2 +- drivers/block/drbd/drbd_receiver.c | 12 ++++++------ drivers/block/drbd/drbd_state.c | 2 +- drivers/block/drbd/drbd_worker.c | 6 +++--- include/linux/drbd_genl.h | 4 ++-- 8 files changed, 49 insertions(+), 49 deletions(-) (limited to 'include') diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index 85e2f4b56a06..b324314768fd 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h @@ -166,7 +166,7 @@ drbd_insert_fault(struct drbd_device *device, unsigned int type) { #define div_floor(A, B) ((A)/(B)) extern struct ratelimit_state drbd_ratelimit_state; -extern struct idr minors; /* RCU, updates: genl_lock() */ +extern struct idr drbd_devices; /* RCU, updates: genl_lock() */ extern struct list_head drbd_connections; /* RCU, updates: genl_lock() */ extern const char *cmdname(enum drbd_packet cmd); @@ -771,7 +771,7 @@ struct drbd_device { static inline struct drbd_device *minor_to_device(unsigned int minor) { - return (struct drbd_device *)idr_find(&minors, minor); + return (struct drbd_device *)idr_find(&drbd_devices, minor); } static inline struct drbd_peer_device *first_peer_device(struct drbd_device *device) @@ -1175,11 +1175,11 @@ extern rwlock_t global_state_lock; extern int conn_lowest_minor(struct drbd_connection *connection); enum drbd_ret_code drbd_create_minor(struct drbd_connection *connection, unsigned int minor, int vnr); -extern void drbd_minor_destroy(struct kref *kref); +extern void drbd_destroy_device(struct kref *kref); extern int set_resource_options(struct drbd_connection *connection, struct res_opts *res_opts); extern struct drbd_connection *conn_create(const char *name, struct res_opts *res_opts); -extern void conn_destroy(struct kref *kref); +extern void drbd_destroy_connection(struct kref *kref); struct drbd_connection *conn_get_by_name(const char *name); extern struct drbd_connection *conn_get_by_addrs(void *my_addr, int my_addr_len, void *peer_addr, int peer_addr_len); diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index b7c858f51fa6..4da017d22f4b 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c @@ -117,7 +117,7 @@ module_param_string(usermode_helper, usermode_helper, sizeof(usermode_helper), 0 /* in 2.6.x, our device mapping and config info contains our virtual gendisks * as member "struct gendisk *vdisk;" */ -struct idr minors; +struct idr drbd_devices; struct list_head drbd_connections; /* list of struct drbd_connection */ struct kmem_cache *drbd_request_cache; @@ -364,7 +364,7 @@ restart: /* Release mod reference taken when thread was started */ - kref_put(&connection->kref, &conn_destroy); + kref_put(&connection->kref, drbd_destroy_connection); module_put(THIS_MODULE); return retval; } @@ -416,7 +416,7 @@ int drbd_thread_start(struct drbd_thread *thi) if (IS_ERR(nt)) { conn_err(connection, "Couldn't start thread\n"); - kref_put(&connection->kref, &conn_destroy); + kref_put(&connection->kref, drbd_destroy_connection); module_put(THIS_MODULE); return false; } @@ -2158,7 +2158,7 @@ static void drbd_release_all_peer_reqs(struct drbd_device *device) } /* caution. no locking. */ -void drbd_minor_destroy(struct kref *kref) +void drbd_destroy_device(struct kref *kref) { struct drbd_device *device = container_of(kref, struct drbd_device, kref); struct drbd_connection *connection = first_peer_device(device)->connection; @@ -2195,7 +2195,7 @@ void drbd_minor_destroy(struct kref *kref) kfree(first_peer_device(device)); kfree(device); - kref_put(&connection->kref, &conn_destroy); + kref_put(&connection->kref, drbd_destroy_connection); } /* One global retry thread, if we need to push back some bio and have it @@ -2301,26 +2301,26 @@ static void drbd_cleanup(void) drbd_genl_unregister(); - idr_for_each_entry(&minors, device, i) { - idr_remove(&minors, device_to_minor(device)); + idr_for_each_entry(&drbd_devices, device, i) { + idr_remove(&drbd_devices, device_to_minor(device)); idr_remove(&first_peer_device(device)->connection->volumes, device->vnr); destroy_workqueue(device->submit.wq); del_gendisk(device->vdisk); /* synchronize_rcu(); No other threads running at this point */ - kref_put(&device->kref, &drbd_minor_destroy); + kref_put(&device->kref, drbd_destroy_device); } /* not _rcu since, no other updater anymore. Genl already unregistered */ list_for_each_entry_safe(connection, tmp, &drbd_connections, connections) { list_del(&connection->connections); /* not _rcu no proc, not other threads */ /* synchronize_rcu(); */ - kref_put(&connection->kref, &conn_destroy); + kref_put(&connection->kref, drbd_destroy_connection); } drbd_destroy_mempools(); unregister_blkdev(DRBD_MAJOR, "drbd"); - idr_destroy(&minors); + idr_destroy(&drbd_devices); printk(KERN_INFO "drbd: module cleanup done.\n"); } @@ -2576,7 +2576,7 @@ fail: return NULL; } -void conn_destroy(struct kref *kref) +void drbd_destroy_connection(struct kref *kref) { struct drbd_connection *connection = container_of(kref, struct drbd_connection, kref); @@ -2688,7 +2688,7 @@ enum drbd_ret_code drbd_create_minor(struct drbd_connection *connection, unsigne device->read_requests = RB_ROOT; device->write_requests = RB_ROOT; - minor_got = idr_alloc(&minors, device, minor, minor + 1, GFP_KERNEL); + minor_got = idr_alloc(&drbd_devices, device, minor, minor + 1, GFP_KERNEL); if (minor_got < 0) { if (minor_got == -ENOSPC) { err = ERR_MINOR_EXISTS; @@ -2725,7 +2725,7 @@ enum drbd_ret_code drbd_create_minor(struct drbd_connection *connection, unsigne out_idr_remove_vol: idr_remove(&connection->volumes, vnr_got); out_idr_remove_minor: - idr_remove(&minors, minor_got); + idr_remove(&drbd_devices, minor_got); synchronize_rcu(); out_no_minor_idr: drbd_bm_cleanup(device); @@ -2736,7 +2736,7 @@ out_no_io_page: out_no_disk: blk_cleanup_queue(q); out_no_q: - kref_put(&connection->kref, &conn_destroy); + kref_put(&connection->kref, drbd_destroy_connection); out_no_peer_device: kfree(device); return err; @@ -2772,7 +2772,7 @@ int __init drbd_init(void) init_waitqueue_head(&drbd_pp_wait); drbd_proc = NULL; /* play safe for drbd_cleanup */ - idr_init(&minors); + idr_init(&drbd_devices); rwlock_init(&global_state_lock); INIT_LIST_HEAD(&drbd_connections); @@ -2863,7 +2863,7 @@ void conn_md_sync(struct drbd_connection *connection) kref_get(&device->kref); rcu_read_unlock(); drbd_md_sync(device); - kref_put(&device->kref, &drbd_minor_destroy); + kref_put(&device->kref, drbd_destroy_device); rcu_read_lock(); } rcu_read_unlock(); diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c index a8c9c86e29f5..83d8c18fb84c 100644 --- a/drivers/block/drbd/drbd_nl.c +++ b/drivers/block/drbd/drbd_nl.c @@ -45,8 +45,8 @@ // int drbd_adm_create_resource(struct sk_buff *skb, struct genl_info *info); // int drbd_adm_delete_resource(struct sk_buff *skb, struct genl_info *info); -int drbd_adm_add_minor(struct sk_buff *skb, struct genl_info *info); -int drbd_adm_delete_minor(struct sk_buff *skb, struct genl_info *info); +int drbd_adm_new_minor(struct sk_buff *skb, struct genl_info *info); +int drbd_adm_del_minor(struct sk_buff *skb, struct genl_info *info); int drbd_adm_new_resource(struct sk_buff *skb, struct genl_info *info); int drbd_adm_del_resource(struct sk_buff *skb, struct genl_info *info); @@ -274,7 +274,7 @@ fail: static int drbd_adm_finish(struct genl_info *info, int retcode) { if (adm_ctx.connection) { - kref_put(&adm_ctx.connection->kref, &conn_destroy); + kref_put(&adm_ctx.connection->kref, drbd_destroy_connection); adm_ctx.connection = NULL; } @@ -517,7 +517,7 @@ static int _try_outdate_peer_async(void *data) conn_try_outdate_peer(connection); - kref_put(&connection->kref, &conn_destroy); + kref_put(&connection->kref, drbd_destroy_connection); return 0; } @@ -529,7 +529,7 @@ void conn_try_outdate_peer_async(struct drbd_connection *connection) opa = kthread_run(_try_outdate_peer_async, connection, "drbd_async_h"); if (IS_ERR(opa)) { conn_err(connection, "out of mem, failed to invoke fence-peer helper\n"); - kref_put(&connection->kref, &conn_destroy); + kref_put(&connection->kref, drbd_destroy_connection); } } @@ -2924,7 +2924,7 @@ static int get_one_status(struct sk_buff *skb, struct netlink_callback *cb) * on each iteration. */ - /* synchronize with conn_create()/conn_destroy() */ + /* synchronize with conn_create()/drbd_destroy_connection() */ rcu_read_lock(); /* revalidate iterator position */ list_for_each_entry_rcu(tmp, &drbd_connections, connections) { @@ -3056,7 +3056,7 @@ int drbd_adm_get_status_all(struct sk_buff *skb, struct netlink_callback *cb) if (!connection) return -ENODEV; - kref_put(&connection->kref, &conn_destroy); /* get_one_status() (re)validates connection by itself */ + kref_put(&connection->kref, drbd_destroy_connection); /* get_one_status() (re)validates connection by itself */ /* prime iterators, and set "filter" mode mark: * only dump this connection. */ @@ -3266,7 +3266,7 @@ out: return 0; } -int drbd_adm_add_minor(struct sk_buff *skb, struct genl_info *info) +int drbd_adm_new_minor(struct sk_buff *skb, struct genl_info *info) { struct drbd_genlmsghdr *dh = info->userhdr; enum drbd_ret_code retcode; @@ -3303,7 +3303,7 @@ out: return 0; } -static enum drbd_ret_code adm_delete_minor(struct drbd_device *device) +static enum drbd_ret_code adm_del_minor(struct drbd_device *device) { if (device->state.disk == D_DISKLESS && /* no need to be device->state.conn == C_STANDALONE && @@ -3313,17 +3313,17 @@ static enum drbd_ret_code adm_delete_minor(struct drbd_device *device) _drbd_request_state(device, NS(conn, C_WF_REPORT_PARAMS), CS_VERBOSE + CS_WAIT_COMPLETE); idr_remove(&first_peer_device(device)->connection->volumes, device->vnr); - idr_remove(&minors, device_to_minor(device)); + idr_remove(&drbd_devices, device_to_minor(device)); destroy_workqueue(device->submit.wq); del_gendisk(device->vdisk); synchronize_rcu(); - kref_put(&device->kref, &drbd_minor_destroy); + kref_put(&device->kref, drbd_destroy_device); return NO_ERROR; } else return ERR_MINOR_CONFIGURED; } -int drbd_adm_delete_minor(struct sk_buff *skb, struct genl_info *info) +int drbd_adm_del_minor(struct sk_buff *skb, struct genl_info *info) { enum drbd_ret_code retcode; @@ -3333,7 +3333,7 @@ int drbd_adm_delete_minor(struct sk_buff *skb, struct genl_info *info) if (retcode != NO_ERROR) goto out; - retcode = adm_delete_minor(adm_ctx.device); + retcode = adm_del_minor(adm_ctx.device); out: drbd_adm_finish(info, retcode); return 0; @@ -3389,7 +3389,7 @@ int drbd_adm_down(struct sk_buff *skb, struct genl_info *info) /* delete volumes */ idr_for_each_entry(&adm_ctx.connection->volumes, device, i) { - retcode = adm_delete_minor(device); + retcode = adm_del_minor(device); if (retcode != NO_ERROR) { /* "can not happen" */ drbd_msg_put_info("failed to delete volume"); @@ -3401,7 +3401,7 @@ int drbd_adm_down(struct sk_buff *skb, struct genl_info *info) if (conn_lowest_minor(adm_ctx.connection) < 0) { list_del_rcu(&adm_ctx.connection->connections); synchronize_rcu(); - kref_put(&adm_ctx.connection->kref, &conn_destroy); + kref_put(&adm_ctx.connection->kref, drbd_destroy_connection); retcode = NO_ERROR; } else { @@ -3428,7 +3428,7 @@ int drbd_adm_del_resource(struct sk_buff *skb, struct genl_info *info) if (conn_lowest_minor(adm_ctx.connection) < 0) { list_del_rcu(&adm_ctx.connection->connections); synchronize_rcu(); - kref_put(&adm_ctx.connection->kref, &conn_destroy); + kref_put(&adm_ctx.connection->kref, drbd_destroy_connection); retcode = NO_ERROR; } else { diff --git a/drivers/block/drbd/drbd_proc.c b/drivers/block/drbd/drbd_proc.c index f1c81c101fad..2f26e8ffa45b 100644 --- a/drivers/block/drbd/drbd_proc.c +++ b/drivers/block/drbd/drbd_proc.c @@ -236,7 +236,7 @@ static int drbd_seq_show(struct seq_file *seq, void *v) */ rcu_read_lock(); - idr_for_each_entry(&minors, device, i) { + idr_for_each_entry(&drbd_devices, device, i) { if (prev_i != i - 1) seq_printf(seq, "\n"); prev_i = i; diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index e08e99f756a5..791005e163db 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c @@ -1058,7 +1058,7 @@ randomize: clear_bit(DISCARD_MY_DATA, &device->flags); drbd_connected(device); - kref_put(&device->kref, &drbd_minor_destroy); + kref_put(&device->kref, drbd_destroy_device); rcu_read_lock(); } rcu_read_unlock(); @@ -1166,7 +1166,7 @@ static void drbd_flush(struct drbd_connection *connection) drbd_bump_write_ordering(connection, WO_drain_io); } put_ldev(device); - kref_put(&device->kref, &drbd_minor_destroy); + kref_put(&device->kref, drbd_destroy_device); rcu_read_lock(); if (rv) @@ -1409,7 +1409,7 @@ static void conn_wait_active_ee_empty(struct drbd_connection *connection) kref_get(&device->kref); rcu_read_unlock(); drbd_wait_ee_list_empty(device, &device->active_ee); - kref_put(&device->kref, &drbd_minor_destroy); + kref_put(&device->kref, drbd_destroy_device); rcu_read_lock(); } rcu_read_unlock(); @@ -4459,7 +4459,7 @@ static void conn_disconnect(struct drbd_connection *connection) kref_get(&device->kref); rcu_read_unlock(); drbd_disconnected(device); - kref_put(&device->kref, &drbd_minor_destroy); + kref_put(&device->kref, &drbd_destroy_device); rcu_read_lock(); } rcu_read_unlock(); @@ -5199,10 +5199,10 @@ static int connection_finish_peer_reqs(struct drbd_connection *connection) kref_get(&device->kref); rcu_read_unlock(); if (drbd_finish_peer_reqs(device)) { - kref_put(&device->kref, &drbd_minor_destroy); + kref_put(&device->kref, drbd_destroy_device); return 1; } - kref_put(&device->kref, &drbd_minor_destroy); + kref_put(&device->kref, drbd_destroy_device); rcu_read_lock(); } set_bit(SIGNAL_ASENDER, &connection->flags); diff --git a/drivers/block/drbd/drbd_state.c b/drivers/block/drbd/drbd_state.c index 22c4e7d57a80..bb3d5947904d 100644 --- a/drivers/block/drbd/drbd_state.c +++ b/drivers/block/drbd/drbd_state.c @@ -1574,7 +1574,7 @@ static int w_after_conn_state_ch(struct drbd_work *w, int unused) spin_unlock_irq(&connection->req_lock); } } - kref_put(&connection->kref, &conn_destroy); + kref_put(&connection->kref, drbd_destroy_connection); conn_md_sync(connection); diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c index aa1ad7f39786..378e48c983b3 100644 --- a/drivers/block/drbd/drbd_worker.c +++ b/drivers/block/drbd/drbd_worker.c @@ -1458,7 +1458,7 @@ static int _drbd_pause_after(struct drbd_device *device) int i, rv = 0; rcu_read_lock(); - idr_for_each_entry(&minors, odev, i) { + idr_for_each_entry(&drbd_devices, odev, i) { if (odev->state.conn == C_STANDALONE && odev->state.disk == D_DISKLESS) continue; if (!_drbd_may_sync_now(odev)) @@ -1482,7 +1482,7 @@ static int _drbd_resume_next(struct drbd_device *device) int i, rv = 0; rcu_read_lock(); - idr_for_each_entry(&minors, odev, i) { + idr_for_each_entry(&drbd_devices, odev, i) { if (odev->state.conn == C_STANDALONE && odev->state.disk == D_DISKLESS) continue; if (odev->state.aftr_isp) { @@ -1939,7 +1939,7 @@ int drbd_worker(struct drbd_thread *thi) kref_get(&device->kref); rcu_read_unlock(); drbd_device_cleanup(device); - kref_put(&device->kref, &drbd_minor_destroy); + kref_put(&device->kref, drbd_destroy_device); rcu_read_lock(); } rcu_read_unlock(); diff --git a/include/linux/drbd_genl.h b/include/linux/drbd_genl.h index e8c44572b8cb..b14a2e899fea 100644 --- a/include/linux/drbd_genl.h +++ b/include/linux/drbd_genl.h @@ -276,9 +276,9 @@ GENL_op( ) /* add DRBD minor devices as volumes to resources */ -GENL_op(DRBD_ADM_NEW_MINOR, 5, GENL_doit(drbd_adm_add_minor), +GENL_op(DRBD_ADM_NEW_MINOR, 5, GENL_doit(drbd_adm_new_minor), GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED)) -GENL_op(DRBD_ADM_DEL_MINOR, 6, GENL_doit(drbd_adm_delete_minor), +GENL_op(DRBD_ADM_DEL_MINOR, 6, GENL_doit(drbd_adm_del_minor), GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED)) /* add or delete resources */ -- cgit v1.2.3-59-g8ed1b From f44d0436db1ea02f2a08bec40a854550a93e90a8 Mon Sep 17 00:00:00 2001 From: Andreas Gruenbacher Date: Fri, 22 Jul 2011 13:53:19 +0200 Subject: drbd: Define the size of res_opts->cpu_mask in a single place Signed-off-by: Andreas Gruenbacher Signed-off-by: Philipp Reisner --- drivers/block/drbd/drbd_main.c | 3 +-- include/linux/drbd.h | 2 ++ include/linux/drbd_genl.h | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index e07446e19c74..59a58e896cf5 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c @@ -2503,8 +2503,7 @@ int set_resource_options(struct drbd_resource *resource, struct res_opts *res_op /* silently ignore cpu mask on UP kernel */ if (nr_cpu_ids > 1 && res_opts->cpu_mask[0] != 0) { - /* FIXME: Get rid of constant 32 here */ - err = bitmap_parse(res_opts->cpu_mask, 32, + err = bitmap_parse(res_opts->cpu_mask, DRBD_CPU_MASK_SIZE, cpumask_bits(new_cpu_mask), nr_cpu_ids); if (err) { drbd_warn(resource, "bitmap_parse() failed with %d\n", err); diff --git a/include/linux/drbd.h b/include/linux/drbd.h index de7d74ab3de6..6f60136da873 100644 --- a/include/linux/drbd.h +++ b/include/linux/drbd.h @@ -382,4 +382,6 @@ enum drbd_timeout_flag { #define DRBD_MD_INDEX_FLEX_EXT -2 #define DRBD_MD_INDEX_FLEX_INT -3 +#define DRBD_CPU_MASK_SIZE 32 + #endif diff --git a/include/linux/drbd_genl.h b/include/linux/drbd_genl.h index b14a2e899fea..4193f5f2636c 100644 --- a/include/linux/drbd_genl.h +++ b/include/linux/drbd_genl.h @@ -135,7 +135,7 @@ GENL_struct(DRBD_NLA_DISK_CONF, 3, disk_conf, ) GENL_struct(DRBD_NLA_RESOURCE_OPTS, 4, res_opts, - __str_field_def(1, DRBD_GENLA_F_MANDATORY, cpu_mask, 32) + __str_field_def(1, DRBD_GENLA_F_MANDATORY, cpu_mask, DRBD_CPU_MASK_SIZE) __u32_field_def(2, DRBD_GENLA_F_MANDATORY, on_no_data, DRBD_ON_NO_DATA_DEF) ) -- cgit v1.2.3-59-g8ed1b From d9f65229f6257842eb7badef015719432b3d16a6 Mon Sep 17 00:00:00 2001 From: Andreas Gruenbacher Date: Thu, 1 Sep 2011 13:18:31 +0200 Subject: drbd: Move string function prototypes from linux/drbd.h to drbd_string.h Signed-off-by: Andreas Gruenbacher Signed-off-by: Philipp Reisner --- drivers/block/drbd/drbd_int.h | 1 + drivers/block/drbd/drbd_strings.c | 1 + drivers/block/drbd/drbd_strings.h | 9 +++++++++ include/linux/drbd.h | 6 ------ 4 files changed, 11 insertions(+), 6 deletions(-) create mode 100644 drivers/block/drbd/drbd_strings.h (limited to 'include') diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index 7293ea5ccabb..0840e9c96f42 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h @@ -45,6 +45,7 @@ #include #include #include +#include "drbd_strings.h" #include "drbd_state.h" #include "drbd_protocol.h" diff --git a/drivers/block/drbd/drbd_strings.c b/drivers/block/drbd/drbd_strings.c index 58e08ff2b2ce..80b0f63c7075 100644 --- a/drivers/block/drbd/drbd_strings.c +++ b/drivers/block/drbd/drbd_strings.c @@ -24,6 +24,7 @@ */ #include +#include "drbd_strings.h" static const char *drbd_conn_s_names[] = { [C_STANDALONE] = "StandAlone", diff --git a/drivers/block/drbd/drbd_strings.h b/drivers/block/drbd/drbd_strings.h new file mode 100644 index 000000000000..f9923cc88afb --- /dev/null +++ b/drivers/block/drbd/drbd_strings.h @@ -0,0 +1,9 @@ +#ifndef __DRBD_STRINGS_H +#define __DRBD_STRINGS_H + +extern const char *drbd_conn_str(enum drbd_conns); +extern const char *drbd_role_str(enum drbd_role); +extern const char *drbd_disk_str(enum drbd_disk_state); +extern const char *drbd_set_st_err_str(enum drbd_state_rv); + +#endif /* __DRBD_STRINGS_H */ diff --git a/include/linux/drbd.h b/include/linux/drbd.h index 6f60136da873..3dbe9bd57a09 100644 --- a/include/linux/drbd.h +++ b/include/linux/drbd.h @@ -327,12 +327,6 @@ enum drbd_state_rv { SS_AFTER_LAST_ERROR = -22, /* Keep this at bottom */ }; -/* from drbd_strings.c */ -extern const char *drbd_conn_str(enum drbd_conns); -extern const char *drbd_role_str(enum drbd_role); -extern const char *drbd_disk_str(enum drbd_disk_state); -extern const char *drbd_set_st_err_str(enum drbd_state_rv); - #define SHARED_SECRET_MAX 64 #define MDF_CONSISTENT (1 << 0) -- cgit v1.2.3-59-g8ed1b From 7159b1ad3dded9da040b5c608acf3d52d50f661e Mon Sep 17 00:00:00 2001 From: Kent Overstreet Date: Wed, 12 Feb 2014 18:43:32 -0800 Subject: bcache: Better alloc tracepoints Change the invalidate tracepoint to indicate how much data we're invalidating, and change the alloc tracepoints to indicate what offset they're for. Signed-off-by: Kent Overstreet --- drivers/md/bcache/alloc.c | 15 ++++++++++---- drivers/md/bcache/trace.c | 2 +- include/trace/events/bcache.h | 48 ++++++++++++++++++++++++++++++------------- 3 files changed, 46 insertions(+), 19 deletions(-) (limited to 'include') diff --git a/drivers/md/bcache/alloc.c b/drivers/md/bcache/alloc.c index c0d37d082443..a3e1427945f2 100644 --- a/drivers/md/bcache/alloc.c +++ b/drivers/md/bcache/alloc.c @@ -162,10 +162,15 @@ static bool can_invalidate_bucket(struct cache *ca, struct bucket *b) static void invalidate_one_bucket(struct cache *ca, struct bucket *b) { + size_t bucket = b - ca->buckets; + + if (GC_SECTORS_USED(b)) + trace_bcache_invalidate(ca, bucket); + bch_inc_gen(ca, b); b->prio = INITIAL_PRIO; atomic_inc(&b->pin); - fifo_push(&ca->free_inc, b - ca->buckets); + fifo_push(&ca->free_inc, bucket); } /* @@ -301,8 +306,6 @@ static void invalidate_buckets(struct cache *ca) invalidate_buckets_random(ca); break; } - - trace_bcache_alloc_invalidate(ca); } #define allocator_wait(ca, cond) \ @@ -408,8 +411,10 @@ long bch_bucket_alloc(struct cache *ca, unsigned reserve, bool wait) fifo_pop(&ca->free[reserve], r)) goto out; - if (!wait) + if (!wait) { + trace_bcache_alloc_fail(ca, reserve); return -1; + } do { prepare_to_wait(&ca->set->bucket_wait, &w, @@ -425,6 +430,8 @@ long bch_bucket_alloc(struct cache *ca, unsigned reserve, bool wait) out: wake_up_process(ca->alloc_thread); + trace_bcache_alloc(ca, reserve); + if (expensive_debug_checks(ca->set)) { size_t iter; long i; diff --git a/drivers/md/bcache/trace.c b/drivers/md/bcache/trace.c index adbc3df17a80..b7820b0d2621 100644 --- a/drivers/md/bcache/trace.c +++ b/drivers/md/bcache/trace.c @@ -45,7 +45,7 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(bcache_btree_node_split); EXPORT_TRACEPOINT_SYMBOL_GPL(bcache_btree_node_compact); EXPORT_TRACEPOINT_SYMBOL_GPL(bcache_btree_set_root); -EXPORT_TRACEPOINT_SYMBOL_GPL(bcache_alloc_invalidate); +EXPORT_TRACEPOINT_SYMBOL_GPL(bcache_invalidate); EXPORT_TRACEPOINT_SYMBOL_GPL(bcache_alloc_fail); EXPORT_TRACEPOINT_SYMBOL_GPL(bcache_writeback); diff --git a/include/trace/events/bcache.h b/include/trace/events/bcache.h index 7110897c3dfa..8fc2a7134d3c 100644 --- a/include/trace/events/bcache.h +++ b/include/trace/events/bcache.h @@ -399,26 +399,43 @@ TRACE_EVENT(bcache_keyscan, /* Allocator */ -TRACE_EVENT(bcache_alloc_invalidate, - TP_PROTO(struct cache *ca), - TP_ARGS(ca), +TRACE_EVENT(bcache_invalidate, + TP_PROTO(struct cache *ca, size_t bucket), + TP_ARGS(ca, bucket), TP_STRUCT__entry( - __field(unsigned, free ) - __field(unsigned, free_inc ) - __field(unsigned, free_inc_size ) - __field(unsigned, unused ) + __field(unsigned, sectors ) + __field(dev_t, dev ) + __field(__u64, offset ) ), TP_fast_assign( - __entry->free = fifo_used(&ca->free[RESERVE_NONE]); - __entry->free_inc = fifo_used(&ca->free_inc); - __entry->free_inc_size = ca->free_inc.size; - __entry->unused = fifo_used(&ca->unused); + __entry->dev = ca->bdev->bd_dev; + __entry->offset = bucket << ca->set->bucket_bits; + __entry->sectors = GC_SECTORS_USED(&ca->buckets[bucket]); ), - TP_printk("free %u free_inc %u/%u unused %u", __entry->free, - __entry->free_inc, __entry->free_inc_size, __entry->unused) + TP_printk("invalidated %u sectors at %d,%d sector=%llu", + __entry->sectors, MAJOR(__entry->dev), + MINOR(__entry->dev), __entry->offset) +); + +TRACE_EVENT(bcache_alloc, + TP_PROTO(struct cache *ca, size_t bucket), + TP_ARGS(ca, bucket), + + TP_STRUCT__entry( + __field(dev_t, dev ) + __field(__u64, offset ) + ), + + TP_fast_assign( + __entry->dev = ca->bdev->bd_dev; + __entry->offset = bucket << ca->set->bucket_bits; + ), + + TP_printk("allocated %d,%d sector=%llu", MAJOR(__entry->dev), + MINOR(__entry->dev), __entry->offset) ); TRACE_EVENT(bcache_alloc_fail, @@ -426,6 +443,7 @@ TRACE_EVENT(bcache_alloc_fail, TP_ARGS(ca, reserve), TP_STRUCT__entry( + __field(dev_t, dev ) __field(unsigned, free ) __field(unsigned, free_inc ) __field(unsigned, unused ) @@ -433,13 +451,15 @@ TRACE_EVENT(bcache_alloc_fail, ), TP_fast_assign( + __entry->dev = ca->bdev->bd_dev; __entry->free = fifo_used(&ca->free[reserve]); __entry->free_inc = fifo_used(&ca->free_inc); __entry->unused = fifo_used(&ca->unused); __entry->blocked = atomic_read(&ca->set->prio_blocked); ), - TP_printk("free %u free_inc %u unused %u blocked %u", __entry->free, + TP_printk("alloc fail %d,%d free %u free_inc %u unused %u blocked %u", + MAJOR(__entry->dev), MINOR(__entry->dev), __entry->free, __entry->free_inc, __entry->unused, __entry->blocked) ); -- cgit v1.2.3-59-g8ed1b From 2531d9ee61fa08a5a9ab8f002c50779888d232c7 Mon Sep 17 00:00:00 2001 From: Kent Overstreet Date: Mon, 17 Mar 2014 16:55:55 -0700 Subject: bcache: Kill unused freelist This was originally added as at optimization that for various reasons isn't needed anymore, but it does add a lot of nasty corner cases (and it was responsible for some recently fixed bugs). Just get rid of it now. Signed-off-by: Kent Overstreet --- drivers/md/bcache/alloc.c | 140 +++++++++++++++++------------------------- drivers/md/bcache/bcache.h | 28 ++------- drivers/md/bcache/btree.c | 41 +++++++++++-- drivers/md/bcache/btree.h | 2 +- drivers/md/bcache/super.c | 24 +++----- include/trace/events/bcache.h | 6 +- 6 files changed, 112 insertions(+), 129 deletions(-) (limited to 'include') diff --git a/drivers/md/bcache/alloc.c b/drivers/md/bcache/alloc.c index a59ef6147fc7..443d03fbac47 100644 --- a/drivers/md/bcache/alloc.c +++ b/drivers/md/bcache/alloc.c @@ -78,12 +78,6 @@ uint8_t bch_inc_gen(struct cache *ca, struct bucket *b) ca->set->need_gc = max(ca->set->need_gc, bucket_gc_gen(b)); WARN_ON_ONCE(ca->set->need_gc > BUCKET_GC_GEN_MAX); - if (CACHE_SYNC(&ca->set->sb)) { - ca->need_save_prio = max(ca->need_save_prio, - bucket_disk_gen(b)); - WARN_ON_ONCE(ca->need_save_prio > BUCKET_DISK_GEN_MAX); - } - return ret; } @@ -120,58 +114,46 @@ void bch_rescale_priorities(struct cache_set *c, int sectors) mutex_unlock(&c->bucket_lock); } -/* Allocation */ +/* + * Background allocation thread: scans for buckets to be invalidated, + * invalidates them, rewrites prios/gens (marking them as invalidated on disk), + * then optionally issues discard commands to the newly free buckets, then puts + * them on the various freelists. + */ static inline bool can_inc_bucket_gen(struct bucket *b) { - return bucket_gc_gen(b) < BUCKET_GC_GEN_MAX && - bucket_disk_gen(b) < BUCKET_DISK_GEN_MAX; + return bucket_gc_gen(b) < BUCKET_GC_GEN_MAX; } -bool bch_bucket_add_unused(struct cache *ca, struct bucket *b) +bool bch_can_invalidate_bucket(struct cache *ca, struct bucket *b) { - BUG_ON(GC_MARK(b) || GC_SECTORS_USED(b)); + BUG_ON(!ca->set->gc_mark_valid); - if (CACHE_REPLACEMENT(&ca->sb) == CACHE_REPLACEMENT_FIFO) { - unsigned i; - - for (i = 0; i < RESERVE_NONE; i++) - if (!fifo_full(&ca->free[i])) - goto add; - - return false; - } -add: - b->prio = 0; - - if (can_inc_bucket_gen(b) && - fifo_push(&ca->unused, b - ca->buckets)) { - atomic_inc(&b->pin); - return true; - } - - return false; -} - -static bool can_invalidate_bucket(struct cache *ca, struct bucket *b) -{ return (!GC_MARK(b) || GC_MARK(b) == GC_MARK_RECLAIMABLE) && !atomic_read(&b->pin) && can_inc_bucket_gen(b); } -static void invalidate_one_bucket(struct cache *ca, struct bucket *b) +void __bch_invalidate_one_bucket(struct cache *ca, struct bucket *b) { - size_t bucket = b - ca->buckets; + lockdep_assert_held(&ca->set->bucket_lock); + BUG_ON(GC_MARK(b) && GC_MARK(b) != GC_MARK_RECLAIMABLE); if (GC_SECTORS_USED(b)) - trace_bcache_invalidate(ca, bucket); + trace_bcache_invalidate(ca, b - ca->buckets); bch_inc_gen(ca, b); b->prio = INITIAL_PRIO; atomic_inc(&b->pin); - fifo_push(&ca->free_inc, bucket); +} + +static void bch_invalidate_one_bucket(struct cache *ca, struct bucket *b) +{ + __bch_invalidate_one_bucket(ca, b); + + fifo_push(&ca->free_inc, b - ca->buckets); } /* @@ -201,20 +183,7 @@ static void invalidate_buckets_lru(struct cache *ca) ca->heap.used = 0; for_each_bucket(b, ca) { - /* - * If we fill up the unused list, if we then return before - * adding anything to the free_inc list we'll skip writing - * prios/gens and just go back to allocating from the unused - * list: - */ - if (fifo_full(&ca->unused)) - return; - - if (!can_invalidate_bucket(ca, b)) - continue; - - if (!GC_SECTORS_USED(b) && - bch_bucket_add_unused(ca, b)) + if (!bch_can_invalidate_bucket(ca, b)) continue; if (!heap_full(&ca->heap)) @@ -239,7 +208,7 @@ static void invalidate_buckets_lru(struct cache *ca) return; } - invalidate_one_bucket(ca, b); + bch_invalidate_one_bucket(ca, b); } } @@ -255,8 +224,8 @@ static void invalidate_buckets_fifo(struct cache *ca) b = ca->buckets + ca->fifo_last_bucket++; - if (can_invalidate_bucket(ca, b)) - invalidate_one_bucket(ca, b); + if (bch_can_invalidate_bucket(ca, b)) + bch_invalidate_one_bucket(ca, b); if (++checked >= ca->sb.nbuckets) { ca->invalidate_needs_gc = 1; @@ -280,8 +249,8 @@ static void invalidate_buckets_random(struct cache *ca) b = ca->buckets + n; - if (can_invalidate_bucket(ca, b)) - invalidate_one_bucket(ca, b); + if (bch_can_invalidate_bucket(ca, b)) + bch_invalidate_one_bucket(ca, b); if (++checked >= ca->sb.nbuckets / 2) { ca->invalidate_needs_gc = 1; @@ -293,8 +262,7 @@ static void invalidate_buckets_random(struct cache *ca) static void invalidate_buckets(struct cache *ca) { - if (ca->invalidate_needs_gc) - return; + BUG_ON(ca->invalidate_needs_gc); switch (CACHE_REPLACEMENT(&ca->sb)) { case CACHE_REPLACEMENT_LRU: @@ -354,17 +322,10 @@ static int bch_allocator_thread(void *arg) * possibly issue discards to them, then we add the bucket to * the free list: */ - while (1) { + while (!fifo_empty(&ca->free_inc)) { long bucket; - if ((!atomic_read(&ca->set->prio_blocked) || - !CACHE_SYNC(&ca->set->sb)) && - !fifo_empty(&ca->unused)) - fifo_pop(&ca->unused, bucket); - else if (!fifo_empty(&ca->free_inc)) - fifo_pop(&ca->free_inc, bucket); - else - break; + fifo_pop(&ca->free_inc, bucket); if (ca->discard) { mutex_unlock(&ca->set->bucket_lock); @@ -385,9 +346,9 @@ static int bch_allocator_thread(void *arg) * them to the free_inc list: */ +retry_invalidate: allocator_wait(ca, ca->set->gc_mark_valid && - (ca->need_save_prio > 64 || - !ca->invalidate_needs_gc)); + !ca->invalidate_needs_gc); invalidate_buckets(ca); /* @@ -395,13 +356,28 @@ static int bch_allocator_thread(void *arg) * new stuff to them: */ allocator_wait(ca, !atomic_read(&ca->set->prio_blocked)); - if (CACHE_SYNC(&ca->set->sb) && - (!fifo_empty(&ca->free_inc) || - ca->need_save_prio > 64)) + if (CACHE_SYNC(&ca->set->sb)) { + /* + * This could deadlock if an allocation with a btree + * node locked ever blocked - having the btree node + * locked would block garbage collection, but here we're + * waiting on garbage collection before we invalidate + * and free anything. + * + * But this should be safe since the btree code always + * uses btree_check_reserve() before allocating now, and + * if it fails it blocks without btree nodes locked. + */ + if (!fifo_full(&ca->free_inc)) + goto retry_invalidate; + bch_prio_write(ca); + } } } +/* Allocation */ + long bch_bucket_alloc(struct cache *ca, unsigned reserve, bool wait) { DEFINE_WAIT(w); @@ -447,8 +423,6 @@ out: BUG_ON(i == r); fifo_for_each(i, &ca->free_inc, iter) BUG_ON(i == r); - fifo_for_each(i, &ca->unused, iter) - BUG_ON(i == r); } b = ca->buckets + r; @@ -470,17 +444,19 @@ out: return r; } +void __bch_bucket_free(struct cache *ca, struct bucket *b) +{ + SET_GC_MARK(b, 0); + SET_GC_SECTORS_USED(b, 0); +} + void bch_bucket_free(struct cache_set *c, struct bkey *k) { unsigned i; - for (i = 0; i < KEY_PTRS(k); i++) { - struct bucket *b = PTR_BUCKET(c, k, i); - - SET_GC_MARK(b, 0); - SET_GC_SECTORS_USED(b, 0); - bch_bucket_add_unused(PTR_CACHE(c, k, i), b); - } + for (i = 0; i < KEY_PTRS(k); i++) + __bch_bucket_free(PTR_CACHE(c, k, i), + PTR_BUCKET(c, k, i)); } int __bch_bucket_alloc_set(struct cache_set *c, unsigned reserve, diff --git a/drivers/md/bcache/bcache.h b/drivers/md/bcache/bcache.h index 171cda89cb6b..200efc1b5cf8 100644 --- a/drivers/md/bcache/bcache.h +++ b/drivers/md/bcache/bcache.h @@ -195,7 +195,6 @@ struct bucket { atomic_t pin; uint16_t prio; uint8_t gen; - uint8_t disk_gen; uint8_t last_gc; /* Most out of date gen in the btree */ uint8_t gc_gen; uint16_t gc_mark; /* Bitfield used by GC. See below for field */ @@ -426,14 +425,9 @@ struct cache { * their new gen to disk. After prio_write() finishes writing the new * gens/prios, they'll be moved to the free list (and possibly discarded * in the process) - * - * unused: GC found nothing pointing into these buckets (possibly - * because all the data they contained was overwritten), so we only - * need to discard them before they can be moved to the free list. */ DECLARE_FIFO(long, free)[RESERVE_NR]; DECLARE_FIFO(long, free_inc); - DECLARE_FIFO(long, unused); size_t fifo_last_bucket; @@ -442,12 +436,6 @@ struct cache { DECLARE_HEAP(struct bucket *, heap); - /* - * max(gen - disk_gen) for all buckets. When it gets too big we have to - * call prio_write() to keep gens from wrapping. - */ - uint8_t need_save_prio; - /* * If nonzero, we know we aren't going to find any buckets to invalidate * until a gc finishes - otherwise we could pointlessly burn a ton of @@ -848,9 +836,6 @@ static inline bool cached_dev_get(struct cached_dev *dc) /* * bucket_gc_gen() returns the difference between the bucket's current gen and * the oldest gen of any pointer into that bucket in the btree (last_gc). - * - * bucket_disk_gen() returns the difference between the current gen and the gen - * on disk; they're both used to make sure gens don't wrap around. */ static inline uint8_t bucket_gc_gen(struct bucket *b) @@ -858,13 +843,7 @@ static inline uint8_t bucket_gc_gen(struct bucket *b) return b->gen - b->last_gc; } -static inline uint8_t bucket_disk_gen(struct bucket *b) -{ - return b->gen - b->disk_gen; -} - #define BUCKET_GC_GEN_MAX 96U -#define BUCKET_DISK_GEN_MAX 64U #define kobj_attribute_write(n, fn) \ static struct kobj_attribute ksysfs_##n = __ATTR(n, S_IWUSR, NULL, fn) @@ -897,11 +876,14 @@ void bch_submit_bbio(struct bio *, struct cache_set *, struct bkey *, unsigned); uint8_t bch_inc_gen(struct cache *, struct bucket *); void bch_rescale_priorities(struct cache_set *, int); -bool bch_bucket_add_unused(struct cache *, struct bucket *); -long bch_bucket_alloc(struct cache *, unsigned, bool); +bool bch_can_invalidate_bucket(struct cache *, struct bucket *); +void __bch_invalidate_one_bucket(struct cache *, struct bucket *); + +void __bch_bucket_free(struct cache *, struct bucket *); void bch_bucket_free(struct cache_set *, struct bkey *); +long bch_bucket_alloc(struct cache *, unsigned, bool); int __bch_bucket_alloc_set(struct cache_set *, unsigned, struct bkey *, int, bool); int bch_bucket_alloc_set(struct cache_set *, unsigned, diff --git a/drivers/md/bcache/btree.c b/drivers/md/bcache/btree.c index be90596a9e2a..4c340c85b122 100644 --- a/drivers/md/bcache/btree.c +++ b/drivers/md/bcache/btree.c @@ -1641,7 +1641,7 @@ static void btree_gc_start(struct cache_set *c) mutex_unlock(&c->bucket_lock); } -size_t bch_btree_gc_finish(struct cache_set *c) +static size_t bch_btree_gc_finish(struct cache_set *c) { size_t available = 0; struct bucket *b; @@ -1703,9 +1703,6 @@ size_t bch_btree_gc_finish(struct cache_set *c) if (!GC_MARK(b) || GC_MARK(b) == GC_MARK_RECLAIMABLE) available++; - - if (!GC_MARK(b)) - bch_bucket_add_unused(ca, b); } } @@ -1836,6 +1833,42 @@ int bch_btree_check(struct cache_set *c) return btree_root(check_recurse, c, &op); } +void bch_initial_gc_finish(struct cache_set *c) +{ + struct cache *ca; + struct bucket *b; + unsigned i; + + bch_btree_gc_finish(c); + + mutex_lock(&c->bucket_lock); + + /* + * We need to put some unused buckets directly on the prio freelist in + * order to get the allocator thread started - it needs freed buckets in + * order to rewrite the prios and gens, and it needs to rewrite prios + * and gens in order to free buckets. + * + * This is only safe for buckets that have no live data in them, which + * there should always be some of. + */ + for_each_cache(ca, c, i) { + for_each_bucket(b, ca) { + if (fifo_full(&ca->free[RESERVE_PRIO])) + break; + + if (bch_can_invalidate_bucket(ca, b) && + !GC_MARK(b)) { + __bch_invalidate_one_bucket(ca, b); + fifo_push(&ca->free[RESERVE_PRIO], + b - ca->buckets); + } + } + } + + mutex_unlock(&c->bucket_lock); +} + /* Btree insertion */ static bool btree_insert_key(struct btree *b, struct bkey *k, diff --git a/drivers/md/bcache/btree.h b/drivers/md/bcache/btree.h index 3ce371fa7f98..91dfa5e69685 100644 --- a/drivers/md/bcache/btree.h +++ b/drivers/md/bcache/btree.h @@ -252,7 +252,7 @@ int bch_btree_insert(struct cache_set *, struct keylist *, atomic_t *, struct bkey *); int bch_gc_thread_start(struct cache_set *); -size_t bch_btree_gc_finish(struct cache_set *); +void bch_initial_gc_finish(struct cache_set *); void bch_moving_gc(struct cache_set *); int bch_btree_check(struct cache_set *); void bch_initial_mark_key(struct cache_set *, int, struct bkey *); diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c index 2d4a56219ec7..a8c57d59a726 100644 --- a/drivers/md/bcache/super.c +++ b/drivers/md/bcache/super.c @@ -541,9 +541,6 @@ static void prio_io(struct cache *ca, uint64_t bucket, unsigned long rw) closure_sync(cl); } -#define buckets_free(c) "free %zu, free_inc %zu, unused %zu", \ - fifo_used(&c->free), fifo_used(&c->free_inc), fifo_used(&c->unused) - void bch_prio_write(struct cache *ca) { int i; @@ -554,10 +551,6 @@ void bch_prio_write(struct cache *ca) lockdep_assert_held(&ca->set->bucket_lock); - for (b = ca->buckets; - b < ca->buckets + ca->sb.nbuckets; b++) - b->disk_gen = b->gen; - ca->disk_buckets->seq++; atomic_long_add(ca->sb.bucket_size * prio_buckets(ca), @@ -601,14 +594,17 @@ void bch_prio_write(struct cache *ca) mutex_lock(&ca->set->bucket_lock); - ca->need_save_prio = 0; - /* * Don't want the old priorities to get garbage collected until after we * finish writing the new ones, and they're journalled */ - for (i = 0; i < prio_buckets(ca); i++) + for (i = 0; i < prio_buckets(ca); i++) { + if (ca->prio_last_buckets[i]) + __bch_bucket_free(ca, + &ca->buckets[ca->prio_last_buckets[i]]); + ca->prio_last_buckets[i] = ca->prio_buckets[i]; + } } static void prio_read(struct cache *ca, uint64_t bucket) @@ -639,7 +635,7 @@ static void prio_read(struct cache *ca, uint64_t bucket) } b->prio = le16_to_cpu(d->prio); - b->gen = b->disk_gen = b->last_gc = b->gc_gen = d->gen; + b->gen = b->last_gc = b->gc_gen = d->gen; } } @@ -1606,7 +1602,7 @@ static void run_cache_set(struct cache_set *c) goto err; bch_journal_mark(c, &journal); - bch_btree_gc_finish(c); + bch_initial_gc_finish(c); pr_debug("btree_check() done"); /* @@ -1648,7 +1644,7 @@ static void run_cache_set(struct cache_set *c) ca->sb.d[j] = ca->sb.first_bucket + j; } - bch_btree_gc_finish(c); + bch_initial_gc_finish(c); err = "error starting allocator thread"; for_each_cache(ca, c, i) @@ -1794,7 +1790,6 @@ void bch_cache_release(struct kobject *kobj) vfree(ca->buckets); free_heap(&ca->heap); - free_fifo(&ca->unused); free_fifo(&ca->free_inc); for (i = 0; i < RESERVE_NR; i++) @@ -1831,7 +1826,6 @@ static int cache_alloc(struct cache_sb *sb, struct cache *ca) !init_fifo(&ca->free[RESERVE_MOVINGGC], free, GFP_KERNEL) || !init_fifo(&ca->free[RESERVE_NONE], free, GFP_KERNEL) || !init_fifo(&ca->free_inc, free << 2, GFP_KERNEL) || - !init_fifo(&ca->unused, free << 2, GFP_KERNEL) || !init_heap(&ca->heap, free << 3, GFP_KERNEL) || !(ca->buckets = vzalloc(sizeof(struct bucket) * ca->sb.nbuckets)) || diff --git a/include/trace/events/bcache.h b/include/trace/events/bcache.h index 8fc2a7134d3c..c9c3c044b32f 100644 --- a/include/trace/events/bcache.h +++ b/include/trace/events/bcache.h @@ -446,7 +446,6 @@ TRACE_EVENT(bcache_alloc_fail, __field(dev_t, dev ) __field(unsigned, free ) __field(unsigned, free_inc ) - __field(unsigned, unused ) __field(unsigned, blocked ) ), @@ -454,13 +453,12 @@ TRACE_EVENT(bcache_alloc_fail, __entry->dev = ca->bdev->bd_dev; __entry->free = fifo_used(&ca->free[reserve]); __entry->free_inc = fifo_used(&ca->free_inc); - __entry->unused = fifo_used(&ca->unused); __entry->blocked = atomic_read(&ca->set->prio_blocked); ), - TP_printk("alloc fail %d,%d free %u free_inc %u unused %u blocked %u", + TP_printk("alloc fail %d,%d free %u free_inc %u blocked %u", MAJOR(__entry->dev), MINOR(__entry->dev), __entry->free, - __entry->free_inc, __entry->unused, __entry->blocked) + __entry->free_inc, __entry->blocked) ); /* Background writeback */ -- cgit v1.2.3-59-g8ed1b