]> Git Repo - linux.git/blobdiff - net/rds/rds.h
RDS: Implement atomic operations
[linux.git] / net / rds / rds.h
index c224b5bb3ba9368fd00fad5f6a25f90d68364ebd..830e2bbb33322f1c617a35128663620f88a00c6c 100644 (file)
@@ -97,6 +97,7 @@ struct rds_connection {
        unsigned int            c_xmit_hdr_off;
        unsigned int            c_xmit_data_off;
        unsigned int            c_xmit_rdma_sent;
+       unsigned int            c_xmit_atomic_sent;
 
        spinlock_t              c_lock;         /* protect msg queues */
        u64                     c_next_tx_seq;
@@ -206,6 +207,64 @@ struct rds_incoming {
        rds_rdma_cookie_t       i_rdma_cookie;
 };
 
+struct rds_mr {
+       struct rb_node          r_rb_node;
+       atomic_t                r_refcount;
+       u32                     r_key;
+
+       /* A copy of the creation flags */
+       unsigned int            r_use_once:1;
+       unsigned int            r_invalidate:1;
+       unsigned int            r_write:1;
+
+       /* This is for RDS_MR_DEAD.
+        * It would be nice & consistent to make this part of the above
+        * bit field here, but we need to use test_and_set_bit.
+        */
+       unsigned long           r_state;
+       struct rds_sock         *r_sock; /* back pointer to the socket that owns us */
+       struct rds_transport    *r_trans;
+       void                    *r_trans_private;
+};
+
+/* Flags for mr->r_state */
+#define RDS_MR_DEAD            0
+
+struct rds_rdma_op {
+       u32                     r_key;
+       u64                     r_remote_addr;
+       unsigned int            r_write:1;
+       unsigned int            r_fence:1;
+       unsigned int            r_notify:1;
+       unsigned int            r_recverr:1;
+       unsigned int            r_mapped:1;
+       unsigned int            r_active:1;
+       struct rds_notifier     *r_notifier;
+       unsigned int            r_bytes;
+       unsigned int            r_nents;
+       unsigned int            r_count;
+       struct scatterlist      *r_sg;
+};
+
+static inline rds_rdma_cookie_t rds_rdma_make_cookie(u32 r_key, u32 offset)
+{
+       return r_key | (((u64) offset) << 32);
+}
+
+static inline u32 rds_rdma_cookie_key(rds_rdma_cookie_t cookie)
+{
+       return cookie;
+}
+
+static inline u32 rds_rdma_cookie_offset(rds_rdma_cookie_t cookie)
+{
+       return cookie >> 32;
+}
+
+/* atomic operation types */
+#define RDS_ATOMIC_TYPE_CSWP           0
+#define RDS_ATOMIC_TYPE_FADD           1
+
 /*
  * m_sock_item and m_conn_item are on lists that are serialized under
  * conn->c_lock.  m_sock_item has additional meaning in that once it is empty
@@ -259,12 +318,36 @@ struct rds_message {
         */
        spinlock_t              m_rs_lock;
        struct rds_sock         *m_rs;
-       struct rds_rdma_op      *m_rdma_op;
        rds_rdma_cookie_t       m_rdma_cookie;
-       struct rds_mr           *m_rdma_mr;
-       unsigned int            m_nents;
-       unsigned int            m_count;
-       struct scatterlist      m_sg[0];
+       struct {
+               struct rm_atomic_op {
+                       int                     op_type;
+                       uint64_t                op_swap_add;
+                       uint64_t                op_compare;
+
+                       u32                     op_rkey;
+                       u64                     op_remote_addr;
+                       unsigned int            op_notify:1;
+                       unsigned int            op_recverr:1;
+                       unsigned int            op_mapped:1;
+                       unsigned int            op_active:1;
+                       struct rds_notifier     *op_notifier;
+                       struct scatterlist      *op_sg;
+
+                       struct rds_mr           *op_rdma_mr;
+               } atomic;
+               struct rm_rdma_op {
+                       struct rds_rdma_op      m_rdma_op;
+                       struct rds_mr           *m_rdma_mr;
+               } rdma;
+               struct rm_data_op {
+                       unsigned int            m_nents;
+                       unsigned int            m_count;
+                       struct scatterlist      *m_sg;
+               } data;
+       };
+       unsigned int            m_used_sgs;
+       unsigned int            m_total_sgs;
 };
 
 /*
@@ -335,6 +418,7 @@ struct rds_transport {
        int (*xmit_cong_map)(struct rds_connection *conn,
                             struct rds_cong_map *map, unsigned long offset);
        int (*xmit_rdma)(struct rds_connection *conn, struct rds_rdma_op *op);
+       int (*xmit_atomic)(struct rds_connection *conn, struct rm_atomic_op *op);
        int (*recv)(struct rds_connection *conn);
        int (*inc_copy_to_user)(struct rds_incoming *inc, struct iovec *iov,
                                size_t size);
@@ -484,6 +568,8 @@ struct rds_statistics {
        uint64_t        s_cong_update_received;
        uint64_t        s_cong_send_error;
        uint64_t        s_cong_send_blocked;
+       uint64_t        s_atomic_cswp;
+       uint64_t        s_atomic_fadd;
 };
 
 /* af_rds.c */
@@ -527,6 +613,7 @@ struct rds_connection *rds_conn_create(__be32 laddr, __be32 faddr,
                                       struct rds_transport *trans, gfp_t gfp);
 struct rds_connection *rds_conn_create_outgoing(__be32 laddr, __be32 faddr,
                               struct rds_transport *trans, gfp_t gfp);
+void rds_conn_shutdown(struct rds_connection *conn);
 void rds_conn_destroy(struct rds_connection *conn);
 void rds_conn_reset(struct rds_connection *conn);
 void rds_conn_drop(struct rds_connection *conn);
@@ -566,7 +653,8 @@ rds_conn_connecting(struct rds_connection *conn)
 
 /* message.c */
 struct rds_message *rds_message_alloc(unsigned int nents, gfp_t gfp);
-struct rds_message *rds_message_copy_from_user(struct iovec *first_iov,
+struct scatterlist *rds_message_alloc_sgs(struct rds_message *rm, int nents);
+int rds_message_copy_from_user(struct rds_message *rm, struct iovec *first_iov,
                                               size_t total_len);
 struct rds_message *rds_message_map_pages(unsigned long *page_addrs, unsigned int total_len);
 void rds_message_populate_header(struct rds_header *hdr, __be16 sport,
@@ -644,6 +732,31 @@ struct rds_message *rds_send_get_message(struct rds_connection *,
 
 /* rdma.c */
 void rds_rdma_unuse(struct rds_sock *rs, u32 r_key, int force);
+int rds_get_mr(struct rds_sock *rs, char __user *optval, int optlen);
+int rds_get_mr_for_dest(struct rds_sock *rs, char __user *optval, int optlen);
+int rds_free_mr(struct rds_sock *rs, char __user *optval, int optlen);
+void rds_rdma_drop_keys(struct rds_sock *rs);
+int rds_rdma_extra_size(struct rds_rdma_args *args);
+int rds_cmsg_rdma_args(struct rds_sock *rs, struct rds_message *rm,
+                         struct cmsghdr *cmsg);
+int rds_cmsg_rdma_dest(struct rds_sock *rs, struct rds_message *rm,
+                         struct cmsghdr *cmsg);
+int rds_cmsg_rdma_args(struct rds_sock *rs, struct rds_message *rm,
+                         struct cmsghdr *cmsg);
+int rds_cmsg_rdma_map(struct rds_sock *rs, struct rds_message *rm,
+                         struct cmsghdr *cmsg);
+void rds_rdma_free_op(struct rds_rdma_op *ro);
+void rds_rdma_send_complete(struct rds_message *rm, int wc_status);
+void rds_atomic_send_complete(struct rds_message *rm, int wc_status);
+int rds_cmsg_atomic(struct rds_sock *rs, struct rds_message *rm,
+                   struct cmsghdr *cmsg);
+
+extern void __rds_put_mr_final(struct rds_mr *mr);
+static inline void rds_mr_put(struct rds_mr *mr)
+{
+       if (atomic_dec_and_test(&mr->r_refcount))
+               __rds_put_mr_final(mr);
+}
 
 /* stats.c */
 DECLARE_PER_CPU_SHARED_ALIGNED(struct rds_statistics, rds_stats);
@@ -681,6 +794,7 @@ extern unsigned int  rds_sysctl_trace_level;
 int __init rds_threads_init(void);
 void rds_threads_exit(void);
 extern struct workqueue_struct *rds_wq;
+void rds_queue_reconnect(struct rds_connection *conn);
 void rds_connect_worker(struct work_struct *);
 void rds_shutdown_worker(struct work_struct *);
 void rds_send_worker(struct work_struct *);
This page took 0.034355 seconds and 4 git commands to generate.