]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
kclient: fix radix_tree_preload vs preempt behavior
authorSage Weil <sage@newdream.net>
Thu, 22 May 2008 18:50:32 +0000 (11:50 -0700)
committerSage Weil <sage@newdream.net>
Thu, 22 May 2008 18:50:32 +0000 (11:50 -0700)
src/kernel/mds_client.c
src/kernel/messenger.c
src/kernel/mon_client.c
src/kernel/osd_client.c

index 28e0a3cbdab82e212fdbc76a477d1830de61ba57..1bffbea43d4b2c1e25011fd6460494b0fa3f018e 100644 (file)
@@ -1015,10 +1015,17 @@ int ceph_mdsc_do_request(struct ceph_mds_client *mdsc,
        BUG_ON(le32_to_cpu(req->r_request->hdr.type) !=
               CEPH_MSG_CLIENT_REQUEST);
 
-       radix_tree_preload(GFP_NOFS);
+       err = radix_tree_preload(GFP_NOFS);
+       if (err < 0) {
+               derr(10, "ENOMEM in ceph_mdsc_do_request\n");
+               return err;
+       }
        spin_lock(&mdsc->lock);
        __register_request(mdsc, req);
+       spin_unlock(&mdsc->lock);
+       radix_tree_preload_end();
 
+       spin_lock(&mdsc->lock);
 retry:
        mds = choose_mds(mdsc, req);
        if (mds < 0) {
@@ -1063,6 +1070,7 @@ retry:
 
        /* send and wait */
        spin_unlock(&mdsc->lock);
+
        dout(10, "do_request %p r_expects_cap=%d\n", req, req->r_expects_cap);
        req->r_request = ceph_msg_maybe_dup(req->r_request);  
        ceph_msg_get(req->r_request);
index 0a38d48849c498034876a53f99486cd0cd75b17f..7c91e9c972d0a47b1dac456a2789ad9e70c007e6 100644 (file)
@@ -1078,7 +1078,10 @@ static void process_accept(struct ceph_connection *con)
        __u32 peer_cseq = le32_to_cpu(con->in_connect_seq);
 
        /* do we have an existing connection for this peer? */
-       radix_tree_preload(GFP_NOFS);
+       if (radix_tree_preload(GFP_NOFS) < 0) {
+               derr(10, "ENOMEM in process_accept\n");
+               return;
+       }
        spin_lock(&msgr->con_lock);
        existing = __get_connection(msgr, &con->peer_addr);
        if (existing) {
@@ -1138,6 +1141,7 @@ static void process_accept(struct ceph_connection *con)
                prepare_write_accept_reply(con, &tag_ready);
        }
        spin_unlock(&msgr->con_lock);
+       radix_tree_preload_end();
 
        ceph_queue_write(con);
        put_connection(con);
@@ -1310,7 +1314,7 @@ struct ceph_messenger *ceph_messenger_create(struct ceph_entity_addr *myaddr)
        spin_lock_init(&msgr->con_lock);
        INIT_LIST_HEAD(&msgr->con_all);
        INIT_LIST_HEAD(&msgr->con_accepting);
-       INIT_RADIX_TREE(&msgr->con_tree, GFP_KERNEL);
+       INIT_RADIX_TREE(&msgr->con_tree, GFP_ATOMIC);
 
        msgr->zero_page = alloc_page(GFP_KERNEL | __GFP_ZERO);
        if (!msgr->zero_page) {
@@ -1456,7 +1460,6 @@ int ceph_msg_send(struct ceph_messenger *msgr, struct ceph_msg *msg,
        msg->hdr.src = msgr->inst;
 
        /* do we have the connection? */
-       radix_tree_preload(GFP_NOFS);
        spin_lock(&msgr->con_lock);
        con = __get_connection(msgr, &msg->hdr.dst.addr);
        if (!con) {
@@ -1465,6 +1468,13 @@ int ceph_msg_send(struct ceph_messenger *msgr, struct ceph_msg *msg,
                newcon = new_connection(msgr);
                if (IS_ERR(newcon))
                        return PTR_ERR(con);
+
+               ret = radix_tree_preload(GFP_NOFS);
+               if (ret < 0) {
+                       derr(10, "ENOMEM in ceph_msg_send\n");
+                       return ret;
+               }
+                       
                spin_lock(&msgr->con_lock);
                con = __get_connection(msgr, &msg->hdr.dst.addr);
                if (con) {
@@ -1481,12 +1491,15 @@ int ceph_msg_send(struct ceph_messenger *msgr, struct ceph_msg *msg,
                             "%u.%u.%u.%u:%u\n", con,
                             IPQUADPORT(msg->hdr.dst.addr.ipaddr));
                }
+               spin_unlock(&msgr->con_lock);
+               radix_tree_preload_end();
        } else {
                dout(10, "ceph_msg_send had connection %p to peer "
                     "%u.%u.%u.%u:%u\n", con,
                     IPQUADPORT(msg->hdr.dst.addr.ipaddr));
+               spin_unlock(&msgr->con_lock);
        }
-       spin_unlock(&msgr->con_lock);
+
        con->delay = timeout;
        dout(10, "ceph_msg_send delay = %lu\n", con->delay);
 
index bfdb5f560f60f2b00daff440c57be5597c4bd487..5d2ee55650a365307aeb55517058f9f293f41465 100644 (file)
@@ -308,11 +308,18 @@ int ceph_monc_do_statfs(struct ceph_mon_client *monc, struct ceph_statfs *buf)
        init_completion(&req.completion);
 
        /* register request */
+       err = radix_tree_preload(GFP_NOFS);
+       if (err < 0) {
+               derr(10, "ENOMEM in do_statfs\n");
+               return err;
+       }
+
        spin_lock(&monc->lock);
        req.tid = ++monc->last_tid;
        req.last_attempt = jiffies;
        radix_tree_insert(&monc->statfs_request_tree, req.tid, &req);
        spin_unlock(&monc->lock);
+       radix_tree_preload_end();
 
        /* send request */
        err = send_statfs(monc, req.tid);
@@ -337,7 +344,7 @@ int ceph_monc_init(struct ceph_mon_client *monc, struct ceph_client *cl)
                return -ENOMEM;
        spin_lock_init(&monc->lock);
        mutex_init(&monc->req_mutex);
-       INIT_RADIX_TREE(&monc->statfs_request_tree, GFP_NOFS);
+       INIT_RADIX_TREE(&monc->statfs_request_tree, GFP_ATOMIC);
        INIT_DELAYED_WORK(&monc->mds_delayed_work, do_request_mdsmap);
        INIT_DELAYED_WORK(&monc->osd_delayed_work, do_request_osdmap);
        INIT_DELAYED_WORK(&monc->umount_delayed_work, do_request_umount);
index c3b5085478ec2da66ad20426a3ecad26002818b7..f17bb14ec526705374b1b319f8d9fe948c077bd5 100644 (file)
@@ -94,7 +94,11 @@ static int register_request(struct ceph_osd_client *osdc,
        struct ceph_osd_request_head *head = req->r_request->front.iov_base;
        int rc;
 
-       radix_tree_preload(GFP_NOFS);
+       rc = radix_tree_preload(GFP_NOFS);
+       if (rc < 0) {
+               derr(10, "ENOMEM in register_request\n");
+               return rc;
+       }
 
        spin_lock(&osdc->request_lock);
        req->r_tid = head->tid = ++osdc->last_tid;
@@ -113,6 +117,8 @@ static int register_request(struct ceph_osd_client *osdc,
        osdc->nr_requests++;
 
        spin_unlock(&osdc->request_lock);
+       radix_tree_preload_end();
+       
        return rc;
 }
 
@@ -521,7 +527,7 @@ void ceph_osdc_init(struct ceph_osd_client *osdc, struct ceph_client *client)
        spin_lock_init(&osdc->request_lock);
        osdc->last_tid = 0;
        osdc->nr_requests = 0;
-       INIT_RADIX_TREE(&osdc->request_tree, GFP_NOFS);
+       INIT_RADIX_TREE(&osdc->request_tree, GFP_ATOMIC);
        INIT_DELAYED_WORK(&osdc->timeout_work, handle_timeout);
 }