mem: provide thread-unsafe memseg walk variant
[dpdk.git] / lib / librte_eal / common / include / rte_memory.h
index 3e4c09f..c5a84c3 100644 (file)
@@ -83,6 +83,8 @@ typedef uint64_t rte_iova_t;
 /**
  * Physical memory segment descriptor.
  */
+#define RTE_MEMSEG_FLAG_DO_NOT_FREE (1 << 0)
+/**< Prevent this segment from being freed back to the OS. */
 struct rte_memseg {
        RTE_STD_C11
        union {
@@ -99,6 +101,7 @@ struct rte_memseg {
        int32_t socket_id;          /**< NUMA socket ID. */
        uint32_t nchannel;          /**< Number of channels. */
        uint32_t nrank;             /**< Number of ranks. */
+       uint32_t flags;             /**< Memseg-specific flags */
 } __rte_packed;
 
 /**
@@ -260,6 +263,42 @@ rte_memseg_contig_walk(rte_memseg_contig_walk_t func, void *arg);
 int __rte_experimental
 rte_memseg_list_walk(rte_memseg_list_walk_t func, void *arg);
 
+/**
+ * Walk list of all memsegs without performing any locking.
+ *
+ * @note This function does not perform any locking, and is only safe to call
+ *       from within memory-related callback functions.
+ *
+ * @param func
+ *   Iterator function
+ * @param arg
+ *   Argument passed to iterator
+ * @return
+ *   0 if walked over the entire list
+ *   1 if stopped by the user
+ *   -1 if user function reported error
+ */
+int __rte_experimental
+rte_memseg_walk_thread_unsafe(rte_memseg_walk_t func, void *arg);
+
+/**
+ * Walk each VA-contiguous area without performing any locking.
+ *
+ * @note This function does not perform any locking, and is only safe to call
+ *       from within memory-related callback functions.
+ *
+ * @param func
+ *   Iterator function
+ * @param arg
+ *   Argument passed to iterator
+ * @return
+ *   0 if walked over the entire list
+ *   1 if stopped by the user
+ *   -1 if user function reported error
+ */
+int __rte_experimental
+rte_memseg_contig_walk_thread_unsafe(rte_memseg_contig_walk_t func, void *arg);
+
 /**
  * Dump the physical memory layout to a file.
  *
@@ -327,7 +366,7 @@ enum rte_mem_event {
  * Function typedef used to register callbacks for memory events.
  */
 typedef void (*rte_mem_event_callback_t)(enum rte_mem_event event_type,
-               const void *addr, size_t len);
+               const void *addr, size_t len, void *arg);
 
 /**
  * Function used to register callbacks for memory events.
@@ -336,19 +375,27 @@ typedef void (*rte_mem_event_callback_t)(enum rte_mem_event event_type,
  *       therefore some functions (e.g. `rte_memseg_walk()`) will cause a
  *       deadlock when called from within such callbacks.
  *
+ * @note mem event callbacks not being supported is an expected error condition,
+ *       so user code needs to handle this situation. In these cases, return
+ *       value will be -1, and rte_errno will be set to ENOTSUP.
+ *
  * @param name
  *   Name associated with specified callback to be added to the list.
  *
  * @param clb
  *   Callback function pointer.
  *
+ * @param arg
+ *   Argument to pass to the callback.
+ *
  * @return
  *   0 on successful callback register
  *   -1 on unsuccessful callback register, with rte_errno value indicating
  *   reason for failure.
  */
 int __rte_experimental
-rte_mem_event_callback_register(const char *name, rte_mem_event_callback_t clb);
+rte_mem_event_callback_register(const char *name, rte_mem_event_callback_t clb,
+               void *arg);
 
 /**
  * Function used to unregister callbacks for memory events.
@@ -356,13 +403,83 @@ rte_mem_event_callback_register(const char *name, rte_mem_event_callback_t clb);
  * @param name
  *   Name associated with specified callback to be removed from the list.
  *
+ * @param arg
+ *   Argument to look for among callbacks with specified callback name.
+ *
+ * @return
+ *   0 on successful callback unregister
+ *   -1 on unsuccessful callback unregister, with rte_errno value indicating
+ *   reason for failure.
+ */
+int __rte_experimental
+rte_mem_event_callback_unregister(const char *name, void *arg);
+
+
+#define RTE_MEM_ALLOC_VALIDATOR_NAME_LEN 64
+/**< maximum length of alloc validator name */
+/**
+ * Function typedef used to register memory allocation validation callbacks.
+ *
+ * Returning 0 will allow allocation attempt to continue. Returning -1 will
+ * prevent allocation from succeeding.
+ */
+typedef int (*rte_mem_alloc_validator_t)(int socket_id,
+               size_t cur_limit, size_t new_len);
+
+/**
+ * @brief Register validator callback for memory allocations.
+ *
+ * Callbacks registered by this function will be called right before memory
+ * allocator is about to trigger allocation of more pages from the system if
+ * said allocation will bring total memory usage above specified limit on
+ * specified socket. User will be able to cancel pending allocation if callback
+ * returns -1.
+ *
+ * @note callbacks will happen while memory hotplug subsystem is write-locked,
+ *       therefore some functions (e.g. `rte_memseg_walk()`) will cause a
+ *       deadlock when called from within such callbacks.
+ *
+ * @note validator callbacks not being supported is an expected error condition,
+ *       so user code needs to handle this situation. In these cases, return
+ *       value will be -1, and rte_errno will be set to ENOTSUP.
+ *
+ * @param name
+ *   Name associated with specified callback to be added to the list.
+ *
+ * @param clb
+ *   Callback function pointer.
+ *
+ * @param socket_id
+ *   Socket ID on which to watch for allocations.
+ *
+ * @param limit
+ *   Limit above which to trigger callbacks.
+ *
+ * @return
+ *   0 on successful callback register
+ *   -1 on unsuccessful callback register, with rte_errno value indicating
+ *   reason for failure.
+ */
+int __rte_experimental
+rte_mem_alloc_validator_register(const char *name,
+               rte_mem_alloc_validator_t clb, int socket_id, size_t limit);
+
+/**
+ * @brief Unregister validator callback for memory allocations.
+ *
+ * @param name
+ *   Name associated with specified callback to be removed from the list.
+ *
+ * @param socket_id
+ *   Socket ID on which to watch for allocations.
+ *
  * @return
  *   0 on successful callback unregister
  *   -1 on unsuccessful callback unregister, with rte_errno value indicating
  *   reason for failure.
  */
 int __rte_experimental
-rte_mem_event_callback_unregister(const char *name);
+rte_mem_alloc_validator_unregister(const char *name, int socket_id);
 
 #ifdef __cplusplus
 }