aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/drbd/drbd_int.h
diff options
context:
space:
mode:
authorLars Ellenberg <lars.ellenberg@linbit.com>2011-11-28 09:04:49 -0500
committerPhilipp Reisner <philipp.reisner@linbit.com>2012-11-08 10:58:35 -0500
commitb6dd1a89767bc33e9c98b3195f8925b46c5c95f3 (patch)
treee82371062171f5cade79cb0c4a6cd22486b5f082 /drivers/block/drbd/drbd_int.h
parentd5b27b01f17ef1f0badc45f9eea521be3457c9cb (diff)
drbd: remove struct drbd_tl_epoch objects (barrier works)
cherry-picked and adapted from drbd 9 devel branch DRBD requests (struct drbd_request) are already on the per resource transfer log list, and carry their epoch number. We do not need to additionally link them on other ring lists in other structs. The drbd sender thread can recognize itself when to send a P_BARRIER, by tracking the currently processed epoch, and how many writes have been processed for that epoch. If the epoch of the request to be processed does not match the currently processed epoch, any writes have been processed in it, a P_BARRIER for this last processed epoch is send out first. The new epoch then becomes the currently processed epoch. To not get stuck in drbd_al_begin_io() waiting for P_BARRIER_ACK, the sender thread also needs to handle the case when the current epoch was closed already, but no new requests are queued yet, and send out P_BARRIER as soon as possible. This is done by comparing the per resource "current transfer log epoch" (tconn->current_tle_nr) with the per connection "currently processed epoch number" (tconn->send.current_epoch_nr), while waiting for new requests to be processed in wait_for_work(). Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com> Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
Diffstat (limited to 'drivers/block/drbd/drbd_int.h')
-rw-r--r--drivers/block/drbd/drbd_int.h45
1 files changed, 27 insertions, 18 deletions
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index c0d0de54ae57..309c121557ae 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -562,12 +562,16 @@ struct drbd_request {
562 struct bio *private_bio; 562 struct bio *private_bio;
563 563
564 struct drbd_interval i; 564 struct drbd_interval i;
565 unsigned int epoch; /* barrier_nr */
566 565
567 /* barrier_nr: used to check on "completion" whether this req was in 566 /* epoch: used to check on "completion" whether this req was in
568 * the current epoch, and we therefore have to close it, 567 * the current epoch, and we therefore have to close it,
569 * starting a new epoch... 568 * causing a p_barrier packet to be send, starting a new epoch.
569 *
570 * This corresponds to "barrier" in struct p_barrier[_ack],
571 * and to "barrier_nr" in struct drbd_epoch (and various
572 * comments/function parameters/local variable names).
570 */ 573 */
574 unsigned int epoch;
571 575
572 struct list_head tl_requests; /* ring list in the transfer log */ 576 struct list_head tl_requests; /* ring list in the transfer log */
573 struct bio *master_bio; /* master bio pointer */ 577 struct bio *master_bio; /* master bio pointer */
@@ -575,14 +579,6 @@ struct drbd_request {
575 unsigned long start_time; 579 unsigned long start_time;
576}; 580};
577 581
578struct drbd_tl_epoch {
579 struct drbd_work w;
580 struct list_head requests; /* requests before */
581 struct drbd_tl_epoch *next; /* pointer to the next barrier */
582 unsigned int br_number; /* the barriers identifier. */
583 int n_writes; /* number of requests attached before this barrier */
584};
585
586struct drbd_epoch { 582struct drbd_epoch {
587 struct drbd_tconn *tconn; 583 struct drbd_tconn *tconn;
588 struct list_head list; 584 struct list_head list;
@@ -845,11 +841,8 @@ struct drbd_tconn { /* is a resource from the config file */
845 unsigned int ko_count; 841 unsigned int ko_count;
846 842
847 spinlock_t req_lock; 843 spinlock_t req_lock;
848 struct drbd_tl_epoch *unused_spare_tle; /* for pre-allocation */ 844
849 struct drbd_tl_epoch *newest_tle; 845 struct list_head transfer_log; /* all requests not yet fully processed */
850 struct drbd_tl_epoch *oldest_tle;
851 struct list_head out_of_sequence_requests;
852 struct list_head barrier_acked_requests;
853 846
854 struct crypto_hash *cram_hmac_tfm; 847 struct crypto_hash *cram_hmac_tfm;
855 struct crypto_hash *integrity_tfm; /* checksums we compute, updates protected by tconn->data->mutex */ 848 struct crypto_hash *integrity_tfm; /* checksums we compute, updates protected by tconn->data->mutex */
@@ -859,18 +852,36 @@ struct drbd_tconn { /* is a resource from the config file */
859 void *int_dig_in; 852 void *int_dig_in;
860 void *int_dig_vv; 853 void *int_dig_vv;
861 854
855 /* receiver side */
862 struct drbd_epoch *current_epoch; 856 struct drbd_epoch *current_epoch;
863 spinlock_t epoch_lock; 857 spinlock_t epoch_lock;
864 unsigned int epochs; 858 unsigned int epochs;
865 enum write_ordering_e write_ordering; 859 enum write_ordering_e write_ordering;
866 atomic_t current_tle_nr; /* transfer log epoch number */ 860 atomic_t current_tle_nr; /* transfer log epoch number */
861 unsigned current_tle_writes; /* writes seen within this tl epoch */
867 862
868 unsigned long last_reconnect_jif; 863 unsigned long last_reconnect_jif;
869 struct drbd_thread receiver; 864 struct drbd_thread receiver;
870 struct drbd_thread worker; 865 struct drbd_thread worker;
871 struct drbd_thread asender; 866 struct drbd_thread asender;
872 cpumask_var_t cpu_mask; 867 cpumask_var_t cpu_mask;
868
869 /* sender side */
873 struct drbd_work_queue sender_work; 870 struct drbd_work_queue sender_work;
871
872 struct {
873 /* whether this sender thread
874 * has processed a single write yet. */
875 bool seen_any_write_yet;
876
877 /* Which barrier number to send with the next P_BARRIER */
878 int current_epoch_nr;
879
880 /* how many write requests have been sent
881 * with req->epoch == current_epoch_nr.
882 * If none, no P_BARRIER will be sent. */
883 unsigned current_epoch_writes;
884 } send;
874}; 885};
875 886
876struct drbd_conf { 887struct drbd_conf {
@@ -1054,7 +1065,6 @@ extern void drbd_calc_cpu_mask(struct drbd_tconn *tconn);
1054extern void tl_release(struct drbd_tconn *, unsigned int barrier_nr, 1065extern void tl_release(struct drbd_tconn *, unsigned int barrier_nr,
1055 unsigned int set_size); 1066 unsigned int set_size);
1056extern void tl_clear(struct drbd_tconn *); 1067extern void tl_clear(struct drbd_tconn *);
1057extern void _tl_add_barrier(struct drbd_tconn *, struct drbd_tl_epoch *);
1058extern void drbd_free_sock(struct drbd_tconn *tconn); 1068extern void drbd_free_sock(struct drbd_tconn *tconn);
1059extern int drbd_send(struct drbd_tconn *tconn, struct socket *sock, 1069extern int drbd_send(struct drbd_tconn *tconn, struct socket *sock,
1060 void *buf, size_t size, unsigned msg_flags); 1070 void *buf, size_t size, unsigned msg_flags);
@@ -1460,7 +1470,6 @@ extern int w_resync_timer(struct drbd_work *, int);
1460extern int w_send_write_hint(struct drbd_work *, int); 1470extern int w_send_write_hint(struct drbd_work *, int);
1461extern int w_make_resync_request(struct drbd_work *, int); 1471extern int w_make_resync_request(struct drbd_work *, int);
1462extern int w_send_dblock(struct drbd_work *, int); 1472extern int w_send_dblock(struct drbd_work *, int);
1463extern int w_send_barrier(struct drbd_work *, int);
1464extern int w_send_read_req(struct drbd_work *, int); 1473extern int w_send_read_req(struct drbd_work *, int);
1465extern int w_prev_work_done(struct drbd_work *, int); 1474extern int w_prev_work_done(struct drbd_work *, int);
1466extern int w_e_reissue(struct drbd_work *, int); 1475extern int w_e_reissue(struct drbd_work *, int);