aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIlya Dryomov <idryomov@gmail.com>2016-04-28 10:07:26 -0400
committerIlya Dryomov <idryomov@gmail.com>2016-05-25 19:12:30 -0400
commit9dd2845ccb40452d4ac943231ea34aade4a02c68 (patch)
treed7c5be5f87c642b45a92eec573a657207b27b899
parent7a28f59bf9fb220cdf56ac6ab539fc4a0ae59414 (diff)
libceph: protect osdc->osd_lru list with a spinlock
OSD client is getting moved from the big per-client lock to a set of per-session locks. The big rwlock would only be held for read most of the time, so a global osdc->osd_lru needs additional protection. Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
-rw-r--r--include/linux/ceph/osd_client.h1
-rw-r--r--net/ceph/osd_client.c29
2 files changed, 19 insertions, 11 deletions
diff --git a/include/linux/ceph/osd_client.h b/include/linux/ceph/osd_client.h
index 2415dc0cb008..486d681694c4 100644
--- a/include/linux/ceph/osd_client.h
+++ b/include/linux/ceph/osd_client.h
@@ -224,6 +224,7 @@ struct ceph_osd_client {
224 struct mutex request_mutex; 224 struct mutex request_mutex;
225 struct rb_root osds; /* osds */ 225 struct rb_root osds; /* osds */
226 struct list_head osd_lru; /* idle osds */ 226 struct list_head osd_lru; /* idle osds */
227 spinlock_t osd_lru_lock;
227 u64 last_tid; /* tid of last request */ 228 u64 last_tid; /* tid of last request */
228 struct rb_root requests; /* pending requests */ 229 struct rb_root requests; /* pending requests */
229 struct list_head req_lru; /* in-flight lru */ 230 struct list_head req_lru; /* in-flight lru */
diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c
index b6950c2c6cc4..d1c8e06f1261 100644
--- a/net/ceph/osd_client.c
+++ b/net/ceph/osd_client.c
@@ -1101,31 +1101,37 @@ static void remove_osd(struct ceph_osd_client *osdc, struct ceph_osd *osd)
1101 } 1101 }
1102} 1102}
1103 1103
1104static void __move_osd_to_lru(struct ceph_osd_client *osdc, 1104static void __move_osd_to_lru(struct ceph_osd *osd)
1105 struct ceph_osd *osd)
1106{ 1105{
1107 dout("%s %p\n", __func__, osd); 1106 struct ceph_osd_client *osdc = osd->o_osdc;
1107
1108 dout("%s osd %p osd%d\n", __func__, osd, osd->o_osd);
1108 BUG_ON(!list_empty(&osd->o_osd_lru)); 1109 BUG_ON(!list_empty(&osd->o_osd_lru));
1109 1110
1111 spin_lock(&osdc->osd_lru_lock);
1110 list_add_tail(&osd->o_osd_lru, &osdc->osd_lru); 1112 list_add_tail(&osd->o_osd_lru, &osdc->osd_lru);
1113 spin_unlock(&osdc->osd_lru_lock);
1114
1111 osd->lru_ttl = jiffies + osdc->client->options->osd_idle_ttl; 1115 osd->lru_ttl = jiffies + osdc->client->options->osd_idle_ttl;
1112} 1116}
1113 1117
1114static void maybe_move_osd_to_lru(struct ceph_osd_client *osdc, 1118static void maybe_move_osd_to_lru(struct ceph_osd *osd)
1115 struct ceph_osd *osd)
1116{ 1119{
1117 dout("%s %p\n", __func__, osd);
1118
1119 if (list_empty(&osd->o_requests) && 1120 if (list_empty(&osd->o_requests) &&
1120 list_empty(&osd->o_linger_requests)) 1121 list_empty(&osd->o_linger_requests))
1121 __move_osd_to_lru(osdc, osd); 1122 __move_osd_to_lru(osd);
1122} 1123}
1123 1124
1124static void __remove_osd_from_lru(struct ceph_osd *osd) 1125static void __remove_osd_from_lru(struct ceph_osd *osd)
1125{ 1126{
1126 dout("__remove_osd_from_lru %p\n", osd); 1127 struct ceph_osd_client *osdc = osd->o_osdc;
1128
1129 dout("%s osd %p osd%d\n", __func__, osd, osd->o_osd);
1130
1131 spin_lock(&osdc->osd_lru_lock);
1127 if (!list_empty(&osd->o_osd_lru)) 1132 if (!list_empty(&osd->o_osd_lru))
1128 list_del_init(&osd->o_osd_lru); 1133 list_del_init(&osd->o_osd_lru);
1134 spin_unlock(&osdc->osd_lru_lock);
1129} 1135}
1130 1136
1131/* 1137/*
@@ -1199,7 +1205,7 @@ static void __unregister_request(struct ceph_osd_client *osdc,
1199 ceph_msg_revoke(req->r_request); 1205 ceph_msg_revoke(req->r_request);
1200 1206
1201 list_del_init(&req->r_osd_item); 1207 list_del_init(&req->r_osd_item);
1202 maybe_move_osd_to_lru(osdc, req->r_osd); 1208 maybe_move_osd_to_lru(req->r_osd);
1203 if (list_empty(&req->r_linger_osd_item)) 1209 if (list_empty(&req->r_linger_osd_item))
1204 req->r_osd = NULL; 1210 req->r_osd = NULL;
1205 } 1211 }
@@ -1248,7 +1254,7 @@ static void __unregister_linger_request(struct ceph_osd_client *osdc,
1248 1254
1249 if (req->r_osd) { 1255 if (req->r_osd) {
1250 list_del_init(&req->r_linger_osd_item); 1256 list_del_init(&req->r_linger_osd_item);
1251 maybe_move_osd_to_lru(osdc, req->r_osd); 1257 maybe_move_osd_to_lru(req->r_osd);
1252 if (list_empty(&req->r_osd_item)) 1258 if (list_empty(&req->r_osd_item))
1253 req->r_osd = NULL; 1259 req->r_osd = NULL;
1254 } 1260 }
@@ -2792,6 +2798,7 @@ int ceph_osdc_init(struct ceph_osd_client *osdc, struct ceph_client *client)
2792 osdc->last_tid = 0; 2798 osdc->last_tid = 0;
2793 osdc->osds = RB_ROOT; 2799 osdc->osds = RB_ROOT;
2794 INIT_LIST_HEAD(&osdc->osd_lru); 2800 INIT_LIST_HEAD(&osdc->osd_lru);
2801 spin_lock_init(&osdc->osd_lru_lock);
2795 osdc->requests = RB_ROOT; 2802 osdc->requests = RB_ROOT;
2796 INIT_LIST_HEAD(&osdc->req_lru); 2803 INIT_LIST_HEAD(&osdc->req_lru);
2797 INIT_LIST_HEAD(&osdc->req_unsent); 2804 INIT_LIST_HEAD(&osdc->req_unsent);