| 164 | } |
| 165 | |
| 166 | int |
| 167 | rte_metrics_update_values(int port_id, |
| 168 | uint16_t key, |
| 169 | const uint64_t *values, |
| 170 | uint32_t count) |
| 171 | { |
| 172 | struct rte_metrics_meta_s *entry; |
| 173 | struct rte_metrics_data_s *stats; |
| 174 | const struct rte_memzone *memzone; |
| 175 | uint16_t idx_metric; |
| 176 | uint16_t idx_value; |
| 177 | uint16_t cnt_setsize; |
| 178 | |
| 179 | if (port_id != RTE_METRICS_GLOBAL && |
| 180 | (port_id < 0 || port_id >= RTE_MAX_ETHPORTS)) |
| 181 | return -EINVAL; |
| 182 | |
| 183 | if (values == NULL) |
| 184 | return -EINVAL; |
| 185 | |
| 186 | memzone = rte_memzone_lookup(RTE_METRICS_MEMZONE_NAME); |
| 187 | if (memzone == NULL) |
| 188 | return -EIO; |
| 189 | stats = memzone->addr; |
| 190 | |
| 191 | rte_spinlock_lock(&stats->lock); |
| 192 | |
| 193 | if (key >= stats->cnt_stats) { |
| 194 | rte_spinlock_unlock(&stats->lock); |
| 195 | return -EINVAL; |
| 196 | } |
| 197 | idx_metric = key; |
| 198 | cnt_setsize = 1; |
| 199 | while (idx_metric < stats->cnt_stats) { |
| 200 | entry = &stats->metadata[idx_metric]; |
| 201 | if (entry->idx_next_stat == 0) |
| 202 | break; |
| 203 | cnt_setsize++; |
| 204 | idx_metric++; |
| 205 | } |
| 206 | /* Check update does not cross set border */ |
| 207 | if (count > cnt_setsize) { |
| 208 | rte_spinlock_unlock(&stats->lock); |
| 209 | return -ERANGE; |
| 210 | } |
| 211 | |
| 212 | if (port_id == RTE_METRICS_GLOBAL) |
| 213 | for (idx_value = 0; idx_value < count; idx_value++) { |
| 214 | idx_metric = key + idx_value; |
| 215 | stats->metadata[idx_metric].global_value = |
| 216 | values[idx_value]; |
| 217 | } |
| 218 | else |
| 219 | for (idx_value = 0; idx_value < count; idx_value++) { |
| 220 | idx_metric = key + idx_value; |
| 221 | stats->metadata[idx_metric].value[port_id] = |
| 222 | values[idx_value]; |
| 223 | } |