orig_report(sk);
 }
 
-/* Note: sk_callback_lock must be locked before calling this function. */
-static void save_listen_callbacks(struct socket *sock)
-{
-       struct sock *sk = sock->sk;
-
-       listen_sock.sk_data_ready = sk->sk_data_ready;
-       listen_sock.sk_state_change = sk->sk_state_change;
-       listen_sock.sk_write_space = sk->sk_write_space;
-       listen_sock.sk_error_report = sk->sk_error_report;
-}
-
 static void restore_callbacks(struct socket *sock)
 {
        struct sock *sk = sock->sk;
        release_sock(sk);
 }
 
-static void add_listen_sock(struct socket *sock, struct listen_connection *con)
-{
-       struct sock *sk = sock->sk;
-
-       lock_sock(sk);
-       save_listen_callbacks(sock);
-       con->sock = sock;
-
-       sk->sk_user_data = con;
-       sk->sk_allocation = GFP_NOFS;
-       /* Install a data_ready callback */
-       sk->sk_data_ready = lowcomms_listen_data_ready;
-       release_sock(sk);
-}
-
 /* Make a socket active */
 static void add_sock(struct socket *sock, struct connection *con)
 {
 
 void dlm_lowcomms_shutdown(void)
 {
-       restore_callbacks(listen_con.sock);
-
-       if (recv_workqueue)
-               flush_workqueue(recv_workqueue);
-       if (send_workqueue)
-               flush_workqueue(send_workqueue);
+       /* stop lowcomms_listen_data_ready calls */
+       lock_sock(listen_con.sock->sk);
+       listen_con.sock->sk->sk_data_ready = listen_sock.sk_data_ready;
+       release_sock(listen_con.sock->sk);
 
+       cancel_work_sync(&listen_con.rwork);
        dlm_close_sock(&listen_con.sock);
 }
 
                return;
        }
 
+       flush_work(&con->swork);
        WARN_ON_ONCE(!force && !list_empty(&con->writequeue));
        clean_one_writequeue(con);
        if (con->othercon)
        if (result < 0)
                goto out;
 
-       save_listen_callbacks(sock);
-       add_listen_sock(sock, &listen_con);
+       lock_sock(sock->sk);
+       listen_sock.sk_data_ready = sock->sk->sk_data_ready;
+       listen_sock.sk_write_space = sock->sk->sk_write_space;
+       listen_sock.sk_error_report = sock->sk->sk_error_report;
+       listen_sock.sk_state_change = sock->sk->sk_state_change;
+
+       listen_con.sock = sock;
+
+       sock->sk->sk_allocation = GFP_NOFS;
+       sock->sk->sk_data_ready = lowcomms_listen_data_ready;
+       release_sock(sock->sk);
 
        result = sock->ops->listen(sock, 5);
        if (result < 0) {